node.js - 使用 .save() 与 findByIdAndUpdate() 从数组中删除项目

标签 node.js mongoose

我正在使用 .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获取对象,然后更新您想要的任何内容,然后保存。当您不需要担心并行性或对同一对象的多个查询时,这是可以的。

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/

相关文章:

javascript - 无法使用动态键访问 process.env 值

javascript - 如何处理nodejs中的竞争条件

Javascript 新对象字段未保存

node.js - Pubnub Node.js 防火墙

javascript - 所有 Node "callback"函数都可能是异步的吗?

node.js - MongoDB - 使用 Mongoose 模式 - 如何告诉 Mongoose 不要保存特定字段

javascript - Mongoose 内部的 `_doc` 是什么(console.log 显示使用它和不使用它的结果相同)

node.js - 在 MongoDB 中按 INC 值查找文档

javascript - 网络 Storm : Different JS language versions in different scopes

node.js - 谷歌云功能从第三方服务器获取数据