将字段插入子文档数组中。意外行为

时间:2015-11-27 16:51:40

标签: javascript mongodb mongodb-query

我正在尝试在每个子文档数组中的每个子文档中插入一个新字段。我有一个半工作脚本,预期结果是ordinal_number插入到每个子文档中,但它似乎插入到集合中每个comments数组的第一个子文档中。

db.posts.find({
"comments.ordinal_number":{"$exists":true}}).forEach(function(data){
   for(var i = 0; i < data.comments.length; i++) {
     db.posts.update(
    { 
         "_id": data._id, 
         "comments.body": data.comments[i].body
     },
     {
         "$set": {
           "comments.$.ordinal_number":
               1
         }
     },true,true
    );
  }
});

输出结果:

    "link" : "cxzdzjkztkqraoqlgcru",
        "author" : "machine",
        "title" : "arbitrary title",
        "comments" : [
            {
                "body" : "...",
                "email" : "ZoROirXN@thUNmWmY.com",
                "author" : "Foo bar",
                "ordinal_number" : 1
            },
            {
                "body" : "...",
                "email" : "eAYtQPfz@kVZCJnev.com",
                "author" : "Foo baz"
            }
]

1 个答案:

答案 0 :(得分:0)

您还需要循环游标和数组条目,然后使用$运算符使用"bulk"操作更新数组中的每个子文档,以获得最高效率。

var bulk = db.posts.initializeOrderedBulkOp();
var count = 0;
db.posts.find().forEach(function(doc) { 
    var nComments = doc.comments.length; 
    for (var i = 0; i < nComments; i++) {
        bulk.find( { 
            '_id': doc._id, 
            'comments': { '$elemMatch': { 'email': doc.comments[i]['email'] } }
        } ).update({
            '$set': { 'comments.$.ordinal_number': 1 } 
        }) 
    } 
    count++;
    if(count % 200 === 0) {   
        // Execute per 200 operations and re-init
        bulk.execute();     
        bulk = db.posts.initializeOrderedBulkOp(); 
     }
})

// Clean up queues.
if (count > 0)  bulk.execute();

请注意,批量API是2.6中的新功能,因此如果您使用的是旧版本,则需要使用.update()方法。

db.posts.find().forEach(function(doc) { 
    var nComments = doc.comments.length; 
    for (var i = 0; i < nComments; i++) {
        db.posts.update( 
            { 
                '_id': doc._id, 
                 'comments': { '$elemMatch': { 'email': doc.comments[i]['email'] } }
            }, 

            { '$set': { 'comments.$.ordinal_number': 1 } }
         ) 
    } 
})