using .save() vs findByIdAndUpdate() for removing item from array

你离开我真会死。 提交于 2021-02-16 19:59:41

问题


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.

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

回答1:


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 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.

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.

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.

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.

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



来源:https://stackoverflow.com/questions/54308553/using-save-vs-findbyidandupdate-for-removing-item-from-array

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!