更新mongodb中数组中的所有元素

时间:2015-10-17 12:26:09

标签: mongodb

我有一个mongodb文档,如:

{
    "name" : "JohnDoe",
    "adds" : [
        {
            "status" : "PENDING",
            "date" : "2015-09-23"
        },
        {
            "status" : "PENDING",
            "date" : "2015-10-01"
        }
    ]
}

我想更新所有元素数组,如:

collection.update({'name':'JohnDoe'}, {'$set':{'adds.status':'APPROVED'}}).

怎么做?

编辑:大多数解决方案都说使用位置运算符来选择数组元素,然后使用运算符来更新该元素。但在我的情况下,我必须更新数组中的每个元素。

1 个答案:

答案 0 :(得分:1)

如前所述,这里的主要问题是在这个长期存在的问题中记录了位置运算符的多个元素的更新:http://jira.mongodb.org/browse/SERVER-1243

因此,基本情况是单个执行不能执行此操作,因此为了处理多个数组元素,您需要一些方法来确定需要更新的元素数量,并为每个元素处理一个更新语句。

一种简化的方法通常是使用Bulk Operations来处理最终作为单个请求和对服务器的响应的“多个”更新操作:

var bulk = db.collection.initializeOrderedBulkOp(),
    count = 0;

db.collection.find({ "name": "John Doe", "adds.status": "PENDING" }).forEach(function(doc) { 
    doc.adds.filter(function(add){ return add.status = "PENDING" }).forEach(function(add) {
        bulk.find({ "_id": doc._id, "adds.status": "PENDING" }).updateOne({
            "$set": { "adds.$.status": "APPROVED" }
        });
        count++;

        // Execute once in 1000 statements created and re-init
        if ( count % 1000 == 0 ) {
            bulk.execute();
            bulk = db.collection.initializeOrderedBulkOp();
        }
    });
});

// Execute any pending operations
if ( count % 1000 != 0 )
    bulk.execute();

如果您更新的文档非常小,或者实际上只有一个文档,那么您可以放弃count检查,只需在所需的循环中附加所有批量更新,然后在所有循环结束时执行一次。< / p>

可以在How to Update Multiple Array Elements上找到更长的解释和替换,但是所有这些都归结为不同的方法来匹配元素以更新和处理positional $更新多次,对于每个匹配的文档或直到没有更多的修改过的文件。