Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongoose updateOne function: don't update if $pull didn't work

I'm using updateOne method like this:

Photo.updateOne(
    {
        "_id": photoId
    },
    {
        "$pull": {
            comments: {
                _id: ObjectID(commentId),
                "user.id": user.id
            }
        },
        "$inc": { "commentCount": -1 },
    },
)

Photo model which contains comments as a array and commentCount as a number. When I run the code it's working but if the photo doesn't have the comment (which I'm trying to pull) it's still incrementing commentCount by -1. What I want is, if the code does not pull any comment in photo comments, don't update the commentCount too. How can I add this rule to my code?

Thanks for help.

like image 922
testaaaa Avatar asked Jun 17 '26 17:06

testaaaa


2 Answers

You can also add both fields comments._id and comments.use.id conditions in query part, if comment is not available then it will skip update and pull part.

Photo.updateOne(
    { 
        _id: photoId,
        comments: {
            $elemMatch: {
                _id: ObjectID(commentId),
                "user.id": user.id
            }
        }
    },
    {
        "$pull": {
            comments: {
                _id: ObjectID(commentId),
                "user.id": user.id
            }
        },
        "$inc": { "commentCount": -1 }
    }
)
like image 122
turivishal Avatar answered Jun 22 '26 10:06

turivishal


There is no such feature existing in Mongo, What you can do if you're using Mongo v4.2+ is use pipelined update, as the name suggests this gives you the power to use a pipeline within an update, hence allowing us to have conditions based on previous results.

Photo.updateOne(
    { "_id": photoId },
    [
        {
            $set: {
              comments: {
                  $filter: {
                     input: "$comments",
                     as: "comment",
                     cond: {
                         $and: [
                           {$ne: ["$$comment._id", ObjectID(commentId)]},
                           {$ne: ["$$comment.user.id", user.id]} //really necessary?
                          ]
                     }
                  }
               }
            }
        },
        {
            $set: {
                commentCount: {$size: "$comments"}
            }
        }
    ]
)

For lesser versions you'll have to split it into 2 calls. no way around it.

-------------- EDIT ---------------

You can update the query to find the document using $elemMatch, if it's not found then it means the comment belonged to someone else and you can throw an error in that case.

Photo.updateOne(
    { 
        _id: photoId,
        comments: {
           $elemMatch: {
               _id: objectID(commentId),
               "user.id": user.id
           }
        }
    },
    {
        "$pull": {
            comments: {
                _id: ObjectID(commentId),
                "user.id": user.id
            }
        },
        "$inc": { "commentCount": -1 }
    }
)
like image 28
Tom Slabbaert Avatar answered Jun 22 '26 10:06

Tom Slabbaert



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!