Web User
Web User

Reputation: 7736

How is findById() + save() different from update() in MongoDB

While trying to update a MongoDB document using Mongoose, can I use a findById() with a save() in the callback, or should I stick with traditional update methods such as findByIdAndModify, findOneAndModify, update(), etc.? Say I want to update the name field of the following document (please see a more elaborate example in the edit at the end, which motivated my question):

{
    "_id": ObjectId("123"),
    "name": "Development"
}

(Mongoose model name for the collection is Category)

I could do this:

Category.update({ "_id" : "123" }, { "name" : "Software Development" }, { new: true })

or I could do this:

Category.findById("123", function(err, category) {
    if (err) throw err;
    category.name = "Software Development";
    category.save();
});

For more elaborate examples, it feels easier to manipulate a JavaScript object that can simply be saved, as opposed to devising a relatively complex update document for the .update() operation. Am I missing something fundamentally important?

Edited 7/21/2016 Responding to the comment from @Cameron, I think a better example is warranted:

{
    "_id": ObjectId("123"),
    "roles": [{
        "roleId": ObjectId("1234"),
        "name": "Leader"
    }, {
        "roleId": ObjectId("1235"),
        "name": "Moderator"
    }, {
        "roleId": ObjectId("1236"),
        "name": "Arbitrator"
    }]
}

What I am trying to do is remove some roles as well as add some roles in the roles array of sub-documents in a single operation. To add role sub-documents, $push can be used and to remove role sub-documents, $pull is used. But if I did something like this:

Person.update({
    "_id": "123"
}, {
    $pull : {
        "roles" : {
            "roleId" : {
                $in : [ "1235", "1236" ]
            }
        }
    },
    $push : {
        "roles" : {
            $each: [{
                "roleId" : ObjectId("1237"),
                "name" : "Developer"
            }]
        }
    }
}

When I try to execute this, I get the error Cannot update 'roles' and 'roles' at the same time, of course. That's when I felt it is easier to find a document, manipulate it any way I want and then save it. In that scenario, I don't know if there is really any other choice for updating the document.

Upvotes: 1

Views: 2796

Answers (1)

Thomas Wolfe
Thomas Wolfe

Reputation: 638

I typically like to use findById() when I am performing more elaborate updates and don't think you are missing anything fundamentally important.

However one method to be aware of in mongoose is findByIdAndUpdate(), this issues a mongodb findAndModify update command and would allow you to perform your first example with the following code: Category.findByIdAndUpdate("123", function(err, savedDoc) {...}).

Upvotes: 2

Related Questions