插入到mongo数组的特定索引

时间:2011-06-20 17:39:04

标签: mongodb

Mongo支持文档中的文档数组。例如,像

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

现在,想象一下我想在任意索引处插入一个任意值

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

我知道您可以使用$和$ set更新值,但不能插入任何内容。只是为了插入特定的索引而必须替换整个数组。

5 个答案:

答案 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>
                              }
                           }
                  }
                )