use*_*830 4 mongoose mongodb node.js express
我想更新具有不同值的多个文档.
我的数据库看起来像这样.
[
{
"_id": 1,
"value": 50
},
{
"_id": 2,
"value": 100
}
]
Run Code Online (Sandbox Code Playgroud)
此查询返回错误,因为我传递的是数组而不是$ set中的对象.
Model.update({_id: {$in: ids}}, {$set: ids.value}, {multi: true};
Run Code Online (Sandbox Code Playgroud)
我希望我的数据库看起来像这样
[
{
"_id": 1,
"value": 4
},
{
"_id": 2,
"value": 27
}
]
Run Code Online (Sandbox Code Playgroud)
假设您有一组对象要在集合中更新匹配的ID,例如
var soldItems = [
{
"_id": 1,
"value": 4
},
{
"_id": 2,
"value": 27
}
];
Run Code Online (Sandbox Code Playgroud)
然后你可以使用forEach()
数组上的方法来迭代它并更新你的集合:
soldItems.forEach(function(item)){
Model.update({"_id": item._id}, {"$set": {"value": item.value }}, callback);
});
Run Code Online (Sandbox Code Playgroud)
或使用承诺作为
var updates = [];
soldItems.forEach(function(item)){
var updatePromise = Model.update({"_id": item._id}, {"$set": {"value": item.value }});
updates.push(updatePromise);
});
Promise.all(updates).then(function(results){
console.log(results);
});
Run Code Online (Sandbox Code Playgroud)
或使用 map()
var updates = soldItems.map(function(item)){
return Model.update({"_id": item._id}, {"$set": {"value": item.value }});
});
Promise.all(updates).then(function(results){
console.log(results);
});
Run Code Online (Sandbox Code Playgroud)
对于较大的阵列,您可以利用批量写入API来获得更好的性能.对于>=4.3.0
支持的Mongoose版本MongoDB Server 3.2.x
,您可以使用bulkWrite()
更新.以下示例显示了如何进行此操作:
var bulkUpdateCallback = function(err, r){
console.log(r.matchedCount);
console.log(r.modifiedCount);
}
// Initialise the bulk operations array
var bulkOps = soldItems.map(function (item) {
return {
"updateOne": {
"filter": { "_id": item._id } ,
"update": { "$set": { "value": item.value } }
}
}
});
// Get the underlying collection via the native node.js driver collection object
Model.collection.bulkWrite(bulkOps, { "ordered": true, w: 1 }, bulkUpdateCallback);
Run Code Online (Sandbox Code Playgroud)
对于~3.8.8, ~3.8.22, 4.x
支持MongoDB Server的Mongoose版本>=2.6.x
,您可以使用Bulk API
如下方法
var bulk = Model.collection.initializeOrderedBulkOp(),
counter = 0;
soldItems.forEach(function(item) {
bulk.find({ "_id": item._id }).updateOne({
"$set": { "value": item.value }
});
counter++;
if (counter % 500 == 0) {
bulk.execute(function(err, r) {
// do something with the result
bulk = Model.collection.initializeOrderedBulkOp();
counter = 0;
});
}
});
// Catch any docs in the queue under or over the 500's
if (counter > 0) {
bulk.execute(function(err,result) {
// do something with the result here
});
}
Run Code Online (Sandbox Code Playgroud)
首先,您的update()
查询不正确..
请参阅此处的文档
Model.update(conditions, update, options, callback);
假设您当前的 db 模型包含这样的文档(正如您所描述的那样):
[
{
"_id": 1,
"value": 50
},
{
"_id": 2,
"value": 100
}
];
Run Code Online (Sandbox Code Playgroud)
并且您在包含要使用当前数据库的文档进行修改的对象(即文档)的数组下方是这样的:
idsArray: [
{
"_id": 1,
"value": 4
},
{
"_id": 2,
"value": 27
}
];
Run Code Online (Sandbox Code Playgroud)
根据我对 mongodb 和 mongoose 的经验,我认为您无法使用单行查询更新所有文档(这是您正在尝试执行的操作)..(PS 我不知道这一点,所以我不确定。 .)
但是为了使您的代码工作,您将执行以下操作:
想法:循环遍历 docs 中的每个文档,idsArray
然后调用 update() 。
所以,这是代码:
idsArray.forEach(function(obj) {
Model.update({_id: obj._id}, {$set: {value: obj.value}});
});
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我假设你_id
在 db docs 中有值,因为它们是在上面写的(即,"_id": 1
..但是如果它们是这样的"_id": ObjectId('1')
[
{
"_id": ObjectId('1'),
"value": 50
},
.....
.....
]
Run Code Online (Sandbox Code Playgroud)
那么你需要转换_id
为ObjectId(obj._id)
in update() 查询..所以你会这样做。
var ObjectId = require('mongodb').ObjectID;
idsArray.forEach(function(obj) {
Model.update({_id: ObjectId(obj._id)}, {$set: {value: obj.value}});
});
Run Code Online (Sandbox Code Playgroud)
PS_id
在继续之前确认它(即,)。
希望这可以帮助。
干杯,