我正在使用 .pull
从 mongo db 中的数组中删除一条记录,它工作正常,但是我在堆栈溢出的某处读到了一条评论(无法再次找到它来发布链接) )让我很困扰,因为它评论说使用 .save
而不是使用 .findByIdAndUpdate
或 .updateOne
我只是想知道这是否准确或主观。
这就是我目前正在做的事情。我检查具有该 id 的产品是否确实存在,如果存在,我从数组中提取该记录。
exports.deleteImg = (req, res, next) => {
const productId = req.params.productId;
const imgId = req.params.imgId;
Product.findById(productId)
.then(product => {
if (!product) {
return res.status(500).json({ message: "Product not found" });
} else {
product.images.pull(imgId);
product.save()
.then(response => {
return res.status(200).json( { message: 'Image deleted'} );
})
}
})
.catch(err => {
console.log(err);
});
};
我认为他们所说的是应该这样做(我在谷歌后找到的一个例子)
users.findByIdAndUpdate(userID,
{$pull: {friends: friend}},
{safe: true, upsert: true},
function(err, doc) {
if(err){
console.log(err);
}else{
//do stuff
}
}
);
最佳答案
主要区别在于,当您使用findById
和save
时,您首先从MongoDB获取对象,然后更新您想要的任何内容,然后保存。当您不需要担心并行性或对同一对象的多个查询时,这是可以的。
findByIdAndUpdate
是原子的。当您多次执行此操作时,MongoDB 将为您处理并行性。按照您的示例,如果对同一个对象同时发出两个请求,并传递 { $pull: {friends:friendId } }
,结果将是预期的:只会拉取一个 friend 来自数组。
但假设您在对象上有一个计数器,例如 friendsTotal
,起始值为 0。并且您到达的端点必须将同一对象的计数器增加 1 两次。
如果您使用findById
,然后增加然后保存
,则会遇到一些问题,因为您正在设置整个值。因此,您首先获取对象,增加到 1,然后更新。但另一个请求也做了同样的事情。您最终会得到 friendsTotal = 1
。
通过findByIdAndUpdate
,您可以使用{ $inc: {friendsTotal: 1 } }
。因此,即使您在同一个对象上同时执行此查询两次,您最终也会得到 friendsTotal = 2
,因为 MongoDB 使用这些更新运算符来更好地处理并行性、数据锁定和更多。
在此处查看有关 $inc
的更多信息:https://docs.mongodb.com/manual/reference/operator/update/inc/
关于node.js - 使用 .save() 与 findByIdAndUpdate() 从数组中删除项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54308553/