如何在NodeJS-Express中使用猫鼬更新多条记录,每条记录都具有唯一的值(各项都不具有相同的值)而不会引起N + 1问题?我有以下情况:
产品:
[
{
_id: "407f191e810c19729de860ea",
title: "....",
in_stock: 100,
},
{
_id: "507f1f77bcf86cd799439011",
title: "....",
in_stock: 100,
},
....
]
然后给出这样的“订单”请求:
[
{
item_id: "507f1f77bcf86cd799439011",
quantity: 5
},
{
item_id: "407f191e810c19729de860ea",
quantity: 8
},
...
]
换句话说,给定一个id,quantity tuples数组,我需要减少数据库中每个对应记录的库存。如何做到而不必对每个项目运行一个查询?
在上面的示例中,数据库中的最终结果应为:
[
{
_id: "407f191e810c19729de860ea",
title: "....",
in_stock: 92,
},
{
_id: "507f1f77bcf86cd799439011",
title: "....",
in_stock: 95,
},
....
]
答案 0 :(得分:2)
好吧,在这种情况下,您可以使用类似这样的代码。但我高度怀疑这是您要实现的目标。
我也曾在项目中尝试过相同的问题,但遇到的唯一方法是按id进行迭代并仅运行不同的查询。
db.Element.update(
{ _id: { $in: ['id1', 'id2', 'id3'] } },
{ $set: { visibility : yourvisibility } }
)
这样的代码应该可以解决问题
updateById(0); //call updates iteration
function updateById(i) {
if (i < order.length) {
Products.findByIdAndUpdate({ _id: order[i]._id }, { in_stock: order[i].in_stock }, (err, data) => {
if (!err) { updateById(i++); }
else{throw err}
});
}
else {
// return
}
}
答案 1 :(得分:2)
您将需要使用id遍历订单数组查找库存中的商品,然后可以更新库存数,例如
order.forEach((item) => {
Products.findByIdandUpdate(item._id,
{$set: {in_stock: (in_stock - item.quantity)}}, {new:true})
.then((updatedItem) => {
if(!updatedItem) {
console.log('Cannot update!');
}
else {
console.log(updatedItem);
}
});
});
答案 2 :(得分:1)
对于那些遇到此问题的人,我尚未找到针对此问题的非N + 1解决方案。为了扩展上述答案,我发现的最佳解决方案是使用异步模块,至少避免潜在的阻塞代码:
itemModel.find({ // find items from ids
'_id': itemIds
}).then(function (items) {
if (items) {
asyncModule.each(items,
function (item, callback) {
item.in_stock -= orderQuantities[item._id];
item.save();
callback(); // tell async that current object is done processing
}, onCompleteFunc);
}
}).catch(handleError);
如果有人对此解决方案有任何意见或改进建议,欢迎反馈。