使用 .save() 与 findByIdAndUpdate() 从数组中删除项目 [英] using .save() vs findByIdAndUpdate() for removing item from array

查看:61
本文介绍了使用 .save() 与 findByIdAndUpdate() 从数组中删除项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 .pull 从 mongo db 中的数组中删除一条记录,它工作正常,但是我在堆栈溢出的某处读到了一条评论(无法再次找到它来发布链接) 困扰着我,因为它评论说使用 .save 而不是使用 .findByIdAndUpdate.updateOne

I am using .pull to remove a record from an array in mongo db and it works fine, but a comment I read somewhere on stack overflow (can't find it again to post the link) is bothering me in that it commented that it was bad to use .save instead of using .findByIdAndUpdate or .updateOne

我只是想知道这是准确的还是主观的.

I just wanted to find out if this is accurate or subjective.

这就是我目前的做法.我检查具有该 ID 的产品是否确实存在,如果存在,则从数组中提取该记录.

This is how I am doing it currently. I check if the product with that id actually exists, and if so I pull that record from the array.

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);
    });
};

我认为他们所说的是应该做这样的事情(我在谷歌之后找到的一个例子)

I think what they were saying though was it should rather be done something like this (an example I found after a google)

users.findByIdAndUpdate(userID,
    {$pull: {friends: friend}},
    {safe: true, upsert: true},
    function(err, doc) {
        if(err){
        console.log(err);
        }else{
        //do stuff
        }
    }
);

推荐答案

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

The main difference is that when you use findById and save, you first get the object from MongoDB and then update whatever you want to and then save. This is ok when you don't need to worry about parallelism or multiple queries to the same object.

findByIdAndUpdate 是原子的.当您多次执行此操作时,MongoDB 会为您处理并行性.按照你的例子,如果在同一个对象上同时发出两个请求,通过 { $pull: {friend:friendId } },结果将是预期的:只会拉一个朋友来自数组.

findByIdAndUpdate is atomic. When you execute this multiple times, MongoDB will take care of the parallelism for you. Folllowing your example, if two requests are made at the same time on the same object, passing { $pull: { friends: friendId } }, the result will be the expected: only one friend will be pulled from the array.

但是,假设您在对象上有一个计数器,例如 friendsTotal,起始值为 0.并且您遇到了必须将计数器加 1 两次的端点,对于同一个对象.

But let's say you've a counter on the object, like friendsTotal with starting value at 0. And you hit the endpoint that must increase the counter by one twice, for the same object.

如果你使用findById,然后增加然后save,你会遇到一些问题,因为你设置的是整个值.所以,你首先得到对象,增加到 1,然后更新.但另一个请求也做了同样的事情.你最终会得到 friendsTotal = 1.

If you use findById, then increase and then save, you'd have some problems because you are setting the whole value. So, you first get the object, increase to 1, and update. But the other request did the same. You'll end up with friendsTotal = 1.

通过findByIdAndUpdate,你可以使用{ $inc: {friendTotal: 1 } }.因此,即使您对同一对象同时执行两次此查询,最终也会得到 friendsTotal = 2,因为 MongoDB 使用这些更新运算符来更好地处理并行性、数据锁定和更多.

With findByIdAndUpdate you could use { $inc: { friendsTotal: 1 } }. So, even if you execute this query twice, on the same time, on the same object, you would end up with friendsTotal = 2, because MongoDB use these update operators to better handle parallelism, data locking and more.

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

See more about $inc here: https://docs.mongodb.com/manual/reference/operator/update/inc/

这篇关于使用 .save() 与 findByIdAndUpdate() 从数组中删除项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆