2016-09-21 256 views
1

我需要使用110M文档对mongodb集合进行批量更新,这些文档更新字段_t,这是从纪元开始的秒数{$type : 1}。我需要将数据库中的每个_t转换为ISODate()大批量更新MongoDB - forEach()文档

我尝试了剧本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()一个回调函数。杰瑞德谢谢你的帮助。

+0

当您运行脚本时,您是否从控制台得到任何日志?你使用哪个MongoDB版本? – chridam

+0

我正在使用'3.2.7',它没有提供任何输出或记录,但我没有明确记录任何内容。 – Jared

+0

建立'bulkOps'以一次包含所有110M操作可能是您的问题。尝试每次获取1000个元素时调用'bulkWrite(bulkOps)',然后清除它并构建下一个1000等。 – JohnnyHK

回答

1

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);  
});