大批量更新MongoDB - forEach()文档

时间:2016-09-21 12:11:37

标签: mongodb mongodb-query

我需要使用110M文档对mongodb集合进行批量更新,这些文档会更新字段_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); 

但是我运行了这个脚本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();

但是我不确定如何引用该文档,而在最初的文档中,我在forEach()上有一个回调函数。

感谢你的帮助,Jared。

1 个答案:

答案 0 :(得分:2)

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

我不知道在mongodb引擎中运行javascript是否支持promises,所以最简单的方法是调用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);      
});