【问题标题】:MongoDB Copy and Update Multiple Documents in same collectionMongoDB 复制和更新同一集合中的多个文档
【发布时间】:2016-11-25 22:13:06
【问题描述】:

我有大约 40000 条记录,我需要更新 planId 字段并将记录复制到同一个集合中。 现在我正在使用基本的

linkModel.find({},callback) & linkModel.insertMany([linksArray],callback)

但这会占用很多时间。 我已经尝试过聚合,但 $out 运算符替换了现有集合,而我想更新它而不是替换。

到目前为止我尝试过的三个步骤:

db.links.aggregate([ { $match: { planId: ObjectId("5732f50a6886e5421259e823") } }, { $out: "temp" } ]);

db.temp.updateMany({planId:ObjectId("5732f50a6886e5421259e823")},{$set:{planId:ObjectId("5791b25f203b5e92316e60c3")}})

db.temp.copyTo("links"),

但即使是 copyTo 方法也很慢。 有更快的方法吗?

【问题讨论】:

    标签: node.js mongodb mongoose mongodb-query aggregation-framework


    【解决方案1】:

    利用 Bulk API 进行批量更新。它们提供了更好的性能,因为您将分批将操作发送到服务器,比如 1000,这更有效,因为您不是将每个请求都发送到服务器,而是每 1000 个请求发送一次。

    下面演示了这种方法,第一个示例使用 MongoDB 版本 >= 2.6 and < 3.2 中可用的 Bulk API。它更新所有 通过将所有 Cost 字段更改为浮点值字段来获取集合中的文档:

    var bulk = db.links.initializeUnorderedBulkOp(),
        counter = 0;
    
    db.links.find({ planId: ObjectId("5732f50a6886e5421259e823") })
            .snapshot().forEach(function (doc) {        
        bulk.find({ "_id": doc._id }).updateOne({ 
            "$set": { "planId": ObjectId("5791b25f203b5e92316e60c3") }
        });
    
        counter++;
        if (counter % 1000 == 0) {
            bulk.execute(); // Execute per 1000 operations 
            // re-initialize every 1000 update statements
            bulk = db.links.initializeUnorderedBulkOp(); 
        }
    })
    // Clean up remaining operations in queue
    if (counter % 1000 != 0) { bulk.execute(); }
    

    下一个示例适用于新的 MongoDB 版本 3.2,该版本从 deprecated 开始具有 Bulk API,并使用 bulkWrite() 提供了一组更新的 api。

    它使用与上面相同的游标,但使用相同的 forEach() 游标方法创建具有批量操作的数组,以将每个批量写入文档推送到数组。因为写入命令可以接受不超过 1000 次操作,所以您需要将操作分组为最多 1000 次操作,并在循环达到 1000 次迭代时重新初始化数组:

    var cursor = db.links.find({ planId: ObjectId("5732f50a6886e5421259e823") }).snapshot(),
        bulkUpdateOps = [];
    
    cursor.forEach(function(doc){        
        bulkUpdateOps.push({ 
            "updateOne": {
                "filter": { "_id": doc._id },
                "update": { "$set": { "planId": ObjectId("5791b25f203b5e92316e60c3") } }
             }
        });
    
        if (bulkUpdateOps.length == 1000) {
            db.links.bulkWrite(bulkUpdateOps);
            bulkUpdateOps = [];
        }
    });         
    
    if (bulkUpdateOps.length > 0) { db.links.bulkWrite(bulkUpdateOps); }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-17
      • 1970-01-01
      • 2012-10-07
      • 2018-05-28
      • 2020-07-17
      • 2015-06-09
      • 2016-11-18
      相关资源
      最近更新 更多