以下代码更新指定对象的数组,如果对象不在数据库中,则插入。它工作正常,但我是mongodb的新手,我不确定这是否安全或快速。
也许我应该使用updateMany?我尝试使用它,但我无法获得与以下代码相同的行为。
mongodb.connect(mongo_url, function(err, db) {
if(err) console.log(err)
else {
var mongo_products_collection = db.collection("products")
mongoUpsert(mongo_products_collection, data_products, function() {
db.close()
})
}
})
function mongoUpsert(collection, data_array, cb) {
var data_length = data_array.length
for (var i=0; i < data_length; i++) {
collection.update(
{product_id: data_array[i].product_id},
data_array[i],
{upsert: true}
)
}
return cb(false)
}
答案 0 :(得分:3)
使用 bulkWrite
API执行更新会更好地处理
mongodb.connect(mongo_url, function(err, db) {
if(err) console.log(err)
else {
var mongo_products_collection = db.collection("products")
mongoUpsert(mongo_products_collection, data_products, function() {
db.close()
})
}
})
function mongoUpsert(collection, data_array, cb) {
var bulkUpdateOps = data_array.map(function(data) {
return {
"updateOne": {
"filter": {
"product_id": data.product_id,
"post_modified": { "$ne": data.post_modified }
},
"update": { "$set": data },
"upsert": true
}
};
});
collection.bulkWrite(bulkUpdateOps, function(err, r) {
// do something with result
});
return cb(false);
}
如果你正在处理更大的数组,即&gt; 1000然后考虑将批量写入服务器的500个写入服务器,这样可以提供更好的性能,因为您没有向服务器发送每个请求,每500个请求只发送一次。
对于批量操作,MongoDB每批执行default internal limit 1000次操作,因此在您对批量大小有一定控制权而不是让MongoDB强加默认值时,选择500个文档是好的,即<幅度>的大型操作1000份文件。因此,对于第一种方法中的上述情况,可以立即写入所有数组,因为它很小,但500选择适用于较大的数组。
var ops = [],
counter = 0;
data_array.forEach(function(data) {
ops.push({
"updateOne": {
"filter": {
"product_id": data.product_id,
"post_modified": { "$ne": data.post_modified }
},
"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
}
}