您可以使用 bulkWrite API 根据您指定的逻辑执行更新,因为它可以更好地处理此问题。
例如,下面的 sn-p 显示了如何执行此操作,假设您已经拥有来自 Web 服务的数据,您需要使用它来更新远程集合:
mongodb.connect(mongo_url, function(err, db) {
if(err) console.log(err);
else {
var mongo_remote_collection = db.collection("remote_collection_name");
/* data is from http call to an external service or ideally
place this within the service callback
*/
mongoUpsert(mongo_remote_collection, data, function() {
db.close();
})
}
})
function mongoUpsert(collection, data_array, cb) {
var ops = data_array.map(function(data) {
return {
"updateOne": {
"filter": {
"_id": data._id, // or any other filtering mechanism to identify a doc
"lastModified": { "$lt": data.lastModified }
},
"update": { "$set": data },
"upsert": true
}
};
});
collection.bulkWrite(ops, function(err, r) {
// do something with result
});
return cb(false);
}
如果来自外部服务的数据很大,那么考虑将写入分批发送到服务器,每批 500 次,这样可以提高性能,因为您不会将每个请求都发送到服务器,而是每 500 个请求发送一次。
对于批量操作,MongoDB 对每个批次强制执行 default internal limit 1000 个操作,因此选择 500 个文档是好的,因为您可以对批次大小进行一些控制,而不是让 MongoDB 强制执行默认值,即对于较大的操作> 1000 个文档的大小。因此,对于第一种方法中的上述情况,可以一次写入所有数组,因为这很小,但 500 选择用于更大的数组。
var ops = [],
counter = 0;
data_array.forEach(function(data) {
ops.push({
"updateOne": {
"filter": {
"_id": data._id,
"lastModified": { "$lt": data.lastModified }
},
"update": { "$set": data },
"upsert": true
}
});
counter++;
if (counter % 500 === 0) {
collection.bulkWrite(ops, function(err, r) {
// do something with result
});
ops = [];
}
})
if (counter % 500 != 0) {
collection.bulkWrite(ops, function(err, r) {
// do something with result
}
}