我有一个非常大的MongoDB,我需要更新,所以我写了一个javascript的事情来做:
for (var i = 0; i < 1000000; i++) {
db.test.update(
{foo_field: dataArray1[i]},
{$set: { bar_field: dataArray2[i]}},
{upsert:false}
)
}
我担心执行此脚本会在短时间内执行太多写操作,并会降低数据库的性能,因此我希望根据复制延迟对更新进行速率限制。
但是,我找不到强制脚本睡眠或等待一定数量毫秒的方法。它抱怨setInterval和setTImeout,说他们没有定义&#34;。这可能在Mongo吗?
答案 0 :(得分:5)
如果您使用MongoDB shell进行更新,则setInterval和setTimeout都不起作用。 MongoDB shell确实具有sleep
功能,因此您可以添加此行
// sleep 100ms after 1000 records inserted
if(1000 === counter) {
sleep(100);
counter = 0;
}
else {
counter++;
}
将此行与记录计数器结合使用,例如插入每1000条记录后,睡眠100毫秒。上面的代码不阻止服务器。
不要与服务器命令Sleep - MongoDB Manual 3.0
混淆无论如何,我不会太担心MongoDB无法处理插入。您可以使用{w:1}作为写入问题,以确保返回游标。最后,据我所知,MongoDB shell并不是异步的,这意味着它不会同时按顺序启动100,000个调用。然而,NodeJS mongo驱动程序是异步的,所以可以使用let say async.js来控制数据流 - 例如,一次批量插入1000个,有1-2个工人。
答案 1 :(得分:4)
您可能需要查看批量API。这将允许您在一次更新中执行所有操作,而无需限制循环。
var MongoClient = require('mongodb').MongoClient
MongoClient.connect('mongodb://127.0.0.1:27017/test', function (err, db) {
if(err){
console.log("DB ERR: " + err);
process.exit();
}else{
console.log("CONNECTED!!");
}
var batch = db.collection("test").initializeUnorderedBulkOp({useLegacyOps: true});
for (var i = 0; i < 5000; i++) {
var query = {foo_field: "foo_" + i };
batch.find(query).upsert().updateOne({$set: {foo: "bar_" + i}});
}
// updates batch of 5000 in one db call
batch.execute(function(batchErr, result) {
if(err){
console.log("BATCH ERR:" , batchErr);
}
if(result){
console.log("BATCH RESULT:", result);
}
db.close();
});
});
> db.test.find().sort({_id:-1}).limit(4)
{ "_id" : ObjectId("5629a60d028bb6308940dc67"), "foo_field" : "foo_4999", "foo" : "bar_4999" }
{ "_id" : ObjectId("5629a60d028bb6308940dc66"), "foo_field" : "foo_4998", "foo" : "bar_4998" }
{ "_id" : ObjectId("5629a60d028bb6308940dc65"), "foo_field" : "foo_4997", "foo" : "bar_4997" }
{ "_id" : ObjectId("5629a60d028bb6308940dc64"), "foo_field" : "foo_4996", "foo" : "bar_4996" }