使用.save()与findByIdAndUpdate()从数组中删除项



我正在使用.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
}
}
);

主要区别在于,当您使用findByIdsave时,您首先从MongoDB获取对象,然后更新您想要的任何内容,然后保存。当您不需要担心对同一对象的并行性或多个查询时,这是可以的。

CCD_ 7是原子的。当您多次执行此操作时,MongoDB将为您处理并行性。按照您的示例,如果在同一对象上同时发出两个请求,并传递{ $pull: { friends: friendId } },则结果将是预期的:只会从数组中提取一个朋友。

但假设对象上有一个计数器,如friendsTotal,起始值为0。对于同一个对象,您到达了必须将计数器增加一倍的端点。

如果您使用findById,然后增加,然后使用save,您会遇到一些问题,因为您正在设置整个值。因此,首先获取对象,将其增加到1,然后进行更新。但另一个请求也是如此。你最终会得到friendsTotal = 1

使用findByIdAndUpdate可以使用{ $inc: { friendsTotal: 1 } }。因此,即使在同一时间、同一对象上执行两次该查询,最终也会得到friendsTotal = 2,因为MongoDB使用这些更新运算符可以更好地处理并行性、数据锁定等问题。

点击此处查看有关$inc的更多信息:https://docs.mongodb.com/manual/reference/operator/update/inc/

最新更新