大量更新 MongoDB - forEach() 文档

Jar*_*red 4 mongodb mongodb-query

我需要对mongodb包含 110M 文档的集合进行批量更新,更新自纪元以来几秒的_t字段。{$type : 1}我需要将_t数据库中的所有内容转换为ISODate().

updateDate.js我尝试了这样的脚本:

var bulkOps = [];

db.siteEvents.find({"_t": {"$exists": true, "$type": 1 }}).forEach(function (doc) { 
    var epoch = doc._t;
    newDate = new ISODate(epoch * 1000);

    bulkOps.push(         
        { 
            "updateOne": { 
                "filter": { "_id": doc._id } ,              
                "update": { "$set": { "_t": newDate } } 
            }         
        }           
    );     
});

db.siteEvents.bulkWrite(bulkOps); 
Run Code Online (Sandbox Code Playgroud)

但我运行了这个脚本mongo <connection details...> updateDate.js,它运行了一段时间但没有进行任何更新。

使用此文档页面作为参考,我得到了这一点:

var bulk = db.siteEvents.initializeUnorderedBulkOp();

bulk.find( { "_t": { $type : 1 } } ).update( { $set: { <UNSURE HOW TO REFERENCE DOC HERE> } } );

bulk.execute();
Run Code Online (Sandbox Code Playgroud)

但我不确定如何引用该文档,而在第一个文档中,我在forEach().

谢谢你的帮助,贾里德。

emk*_*man 5

find()返回异步解析的游标。当您的 forEach 循环完成运行时,db.siteEvents.bulkWrite(bulkOps);已经使用空的bulkOps 数组进行了调用。

我不知道在 mongodb 引擎内运行 javascript 是否支持 Promise,所以最简单的方法是调用find().toArray()然后移动您的循环和回调内的bulkWrite。沿着这些思路:

var bulkOps = [];

db.siteEvents.find({"_t": {"$exists": true, "$type": 1 }}).toArray(function(err, docs) {
    docs.forEach(function (doc) { 
      var epoch = doc._t;
      newDate = new ISODate(epoch * 1000);

      bulkOps.push(         
        { 
            "updateOne": { 
                "filter": { "_id": doc._id } ,              
                "update": { "$set": { "_t": newDate } } 
            }         
        }           
      );
    });
    db.siteEvents.bulkWrite(bulkOps);      
});
Run Code Online (Sandbox Code Playgroud)