我试图在每个子文档数组的每个子文档中插入一个新字段。我有一个半工作脚本,预期结果是将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"
            }
]

最佳答案

您还需要循环游标和数组条目,然后使用$操作符使用"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();


请注意,Bulk 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 } }
         )
    }
})

10-07 22:05