在Mongo数组中插入到特定索引

13

Mongo支持在文档中嵌套文档数组。例如,类似于

{_id: 10, "coll": [1, 2, 3] }

现在,想象一下我想要在任意位置插入任意值

{_id: 10, "coll": [1, {name: 'new val'}, 2, 3] }

我知道你可以使用$和$set来原地更新值,但是没有插入的方法。这让在特定索引处插入元素时必须替换整个数组感觉有些糟糕。

5个回答

19

2.6版本开始,您终于可以做到这一点。您需要使用$position运算符。对于您的特定示例:

db.students.update(
  { _id: 10},
  { $push: {
     coll: {
       $each: [ {name: 'new val'} ],
       $position: 1
     }
  }}
)

1

以下是类似帖子中最有用的答案(不是被选中的答案,但评分最高):

你能否在Mongo中使用$push前缀而不是后缀?

使用$set将3插入到名为“array”的数组的第一个位置。以下是Sergey Nikitin相关答案的示例:

db.test.update({"_id" : ObjectId("513ad0f8afdfe1e6736e49eb")}, 
                 {'$set': {'array.-1':     3}})

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"的项目后插入它),只需在item.coll =赋值之前添加一个for()循环来查找insertPosition(并将其加1,因为您想在name = "foo"之后插入它。

0
使用$position运算符,从2.5.3版本开始可以实现此操作。
必须与$each运算符一起使用。来自文档
db.collection.update( <query>,
                  { $push: {
                              <field>: {
                                         $each: [ <value1>, <value2>, ... ],
                                         $position: <num>
                              }
                           }
                  }
                )

0
关于您的评论:
嗯...对于任何数据库来说,使用并发用户都会有问题...
我会这样做: 在文档中添加最后修改时间戳。加载文档,让用户修改它,并在更新文档时使用时间戳作为过滤器,同时一步更新时间戳。如果更新了0个文档,则知道它在此期间已被修改,您可以要求用户重新加载它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接