我在尝试为此提出逻辑时遇到了一些问题。所以,我想做的是:
lastModified
字段小于我要更新/插入的同一文档中的lastModified
字段时更新基本上,我想更新自上次更新文档后修改过的文档列表。 我可以想到两种蛮力的方法来做到这一点......
首先,查询我的整个集合,尝试手动删除和替换符合条件的文档,添加新文档,然后在删除远程中的所有内容后将所有内容重新插入远程集合。
其次,查询每个项目,然后决定,如果遥控器中有一个项目,我是否要更新或不更新。在处理远程集合时,这似乎非常有用。
如果相关,我正在使用mondodb
npm包进行数据库操作的NodeJS环境。
答案 0 :(得分:0)
您可以使用 bulkWrite
API根据您指定的逻辑执行更新,因为它可以更好地处理此问题。
例如,以下代码段显示了如何解决此问题,假设您已经拥有需要使用以下内容更新远程集合的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次发送给服务器,这样可以提高性能,因为您不是每次请求都向服务器发送一次请求。
对于批量操作,MongoDB每批执行default internal limit 1000次操作,因此在您对批量大小有一定控制权而不是让MongoDB强加默认值时,选择500个文档是好的,即<幅度>的大型操作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
}
}