大批量更新MongoDB-forEach()文档
我需要对大批量更新MongoDB-forEach()文档,mongodb,mongodb-query,Mongodb,Mongodb Query,我需要对mongodb集合进行批量更新,该集合包含110M个文档,用于更新一个字段\u t,该字段是自纪元以来秒数{$type:1}。我需要将数据库中的每个\u t转换为ISODate() 我尝试了这样一个脚本updateDate.js: var bulkOps = []; db.siteEvents.find({"_t": {"$exists": true, "$type": 1 }}).forEach(function (doc) { var epoch = doc._t;
mongodb
集合进行批量更新,该集合包含110M个文档,用于更新一个字段\u t
,该字段是自纪元以来秒数{$type:1}
。我需要将数据库中的每个\u 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 updateDate.js
,它运行了一段时间,但没有进行任何更新
使用此文档页面作为参考,我得出了这一点:
var bulk = db.siteEvents.initializeUnorderedBulkOp();
bulk.find( { "_t": { $type : 1 } } ).update( { $set: { <UNSURE HOW TO REFERENCE DOC HERE> } } );
bulk.execute();
var bulk=db.siteEvents.InitializeUnderedBulkop();
bulk.find({u t:{$type:1}}).update({$set:{});
bulk.execute();
但我不确定如何引用该文档,而在最初的文档中,我在forEach()
上有一个回调函数
感谢您的帮助,Jared。find()
返回异步解析的游标。当forEach循环完成运行时,db.siteEvents.bulkWrite(bulkOps)已使用空bulkOps数组调用代码>
我不知道在mongodb引擎中运行javascript是否支持承诺,因此最简单的方法是调用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);
});
当您运行脚本时,是否从控制台获取任何日志?您使用的是哪个MongoDB版本?我使用的是3.2.7
,它没有提供任何输出或日志记录,但我没有明确记录任何内容。构建bulkOps
以同时包含所有110M操作可能是您的问题。每次达到1000个元素时,尝试调用bulkWrite(bulkOps)
,然后清除它并建立下一个1000个元素,等等。@johnyhkbulkWrite
将自动将数组分割为1000个项目片段,因此这是不必要的。与传递{ordered:false}
作为第二个参数相结合,它将自动地、相当高效地切碎它们并并行运行它们。我刚刚从一个阵列顺利运行了5万次批量操作。