Mongo支持文档中的文档数组。例如,像
{_id: 10, "coll": [1, 2, 3] }
现在,想象一下我想在任意索引处插入一个任意值
{_id: 10, "coll": [1, {name: 'new val'}, 2, 3] }
我知道您可以使用$和$ set更新值,但不能插入任何内容。只是为了插入特定的索引而必须替换整个数组。
答案 0 :(得分:16)
从版本2.6 开始,您最终可以执行此操作。您必须使用$position运算符。对于您的特定示例:
db.students.update(
{ _id: 10},
{ $push: {
coll: {
$each: [ {name: 'new val'} ],
$position: 1
}
}}
)
答案 1 :(得分:1)
以下将解决这个问题:
var insertPosition = 1;
var newItem = {name: 'new val'};
db.myCollection.find({_id: 10}).forEach(function(item)
{
item.coll = item.coll.slice(0, insertPosition).concat(newItem, item.coll.slice(insertPosition));
db.myCollection.save(item);
});
如果insertPosition
是可变的(即,您不确切地知道要插入它的位置,但是您知道要在name = "foo"
的项目之后插入它,只需添加{在for()
分配之前循环{1}}以查找insertPosition(并向其添加1,因为您要在item.coll =
之后插入它。
答案 2 :(得分:1)
从这个类似的帖子得到的方便答案(未选择答案,但评分最高): Can you have mongo $push prepend instead of append?
利用$ set在数组的第一个位置插入3,称为" array"。来自Sergey Nikitin的相关答案的样本:
db.test.update({"_id" : ObjectId("513ad0f8afdfe1e6736e49eb")},
{'$set': {'array.-1': 3}})
答案 3 :(得分:0)
关于你的评论:
嗯..对于并发用户来说,这对任何数据库来说都会有问题......
我要做的是以下内容: 将最后修改的时间戳添加到文档中。加载文档,让用户修改它,并在更新文档时使用timstamp作为过滤器,并在一个步骤中更新时间戳。如果它更新了0个文档,您知道它在此期间已被修改,您可以要求用户重新加载它。
答案 4 :(得分:0)
使用$ position运算符,可以从版本2.5.3开始。
必须与$ each运算符一起使用。来自the documentation:
db.collection.update( <query>,
{ $push: {
<field>: {
$each: [ <value1>, <value2>, ... ],
$position: <num>
}
}
}
)