How to use the mongoose update query in NodeJS

Introduction

Out of all the CRUD operations, the Update operation should be handled with utmost care. There could be hundreds of records in a database. One mistake and you end up updating a wrong record. This can lead to further problems. So the most important part of an Update operation is where we match the record that is to be updated. In mongoose, it is the query part. There are few methods provided by mongoose that could be used for updating documents. In this article, we will discuss these methods focussing on the mongoose update query in NodeJS.

We will use the myteam collection for demonstration.

1
2
3
4
5
6
7
{ "_id" : ObjectId("5e33d379a42ffa019344e3cb"), "name" : "Leonel Messi", "club" : "Barcelona", "country" : "Argentina" }
{ "_id" : ObjectId("5e33d38da42ffa019344e3cc"), "name" : "Cristiano Ronaldo", "club" : "Juventis", "country" : "Portugal" }
{ "_id" : ObjectId("5e33d3c1a42ffa019344e3cd"), "name" : "Sadio Mane", "club" : "Liverpool", "country" : "Egypt" }
{ "_id" : ObjectId("5e33d3f5a42ffa019344e3ce"), "name" : "Sergio Ramos", "club" : "Barcelona", "country" : "Spain" }
{ "_id" : ObjectId("5e33d6c2a42ffa019344e3d0"), "name" : "Tony Kroos", "club" : "Real Madrid", "country" : "France" }
{ "_id" : ObjectId("5e33d6dea42ffa019344e3d1"), "name" : "Paula Dybala", "club" : "Real Madrid", "country" : "Argentina" }
{ "_id" : ObjectId("5e33d711a42ffa019344e3d2"), "name" : "Leroy Sane", "club" : "Manchester City", "country" : "France" }

You see, this collection contains data of some of the best footballers in the world. But some of the documents contain wrong information, for example, the player Sergio Ramos plays for Real Madrid football club, not Barcelona. There are a few more mistakes like this. We will fix this by using different Update operations.

For performing HTTP endpoint testing, we will use the postman tool. You can download the postman tool from www.getpostman.com.

findOneAndUpdate()

So let’s start with a simple method named findOneAndUpdate(). As the name suggests, these methods find a single document and update it. We have to provide a query to match a document. Suppose, multiple documents can match the query. But the findOneAndUpdate() method will update only the very first matched document. All other documents that could match will be ignored. So let’s start by creating a route handler.

1
router.route("/update").put(function(req, res) {});

The above route handler will be invoked when the route ‘/update’ is executed.

We will update the document where the name is “Sadio Mane”. In this document, the country should be “Senegal” instead of “Egypt”. We need to update a single document. So the findOneAndUpdate() is perfect for this case.

1
2
3
4
5
6
7
8
9
10
11
12
router.route("/update").put(function(req, res) {
  myteam.updateOne({ name: "Sadio Mane" }, { country: "Senegal" }, function(
    err,
    result
  ) {
    if (err) {
      res.send(err);
    } else {
      res.json(result);
    }
  });
});

The first argument is the query and second is the update. Let’s execute it using the postman tool.

Image from Gyazo

The findOneAndUpdate() method returns the matched document, not the updated one. We can see, in the returned object, the value of the country field is still “Egypt”. Let’s check through the mongo shell if the operation was successful or not.

1
2
3
4
5
6
7
8
9
> db.myteam.find()
{ "_id" : ObjectId("5e33d379a42ffa019344e3cb"), "name" : "Leonel Messi", "club" : "Barcelona", "country" : "Argentina" }
{ "_id" : ObjectId("5e33d38da42ffa019344e3cc"), "name" : "Cristiano Ronaldo", "club" : "Juventis", "country" : "Portugal" }
{ "_id" : ObjectId("5e33d3c1a42ffa019344e3cd"), "name" : "Sadio Mane", "club" : "Liverpool", "country" : "Senegal" }
{ "_id" : ObjectId("5e33d3f5a42ffa019344e3ce"), "name" : "Sergio Ramos", "club" : "Barcelona", "country" : "Spain" }
{ "_id" : ObjectId("5e33d6c2a42ffa019344e3d0"), "name" : "Tony Kroos", "club" : "Real Madrid", "country" : "France" }
{ "_id" : ObjectId("5e33d6dea42ffa019344e3d1"), "name" : "Paula Dybala", "club" : "Real Madrid", "country" : "Argentina" }
{ "_id" : ObjectId("5e33d711a42ffa019344e3d2"), "name" : "Leroy Sane", "club" : "Manchester City", "country" : "France" }
>

Check the third document from the top. The value of the country field is now “Senegal”.

updateOne()

The updateOne() method is very similar to the findOneAndUpdate() method. It also updates a single document. But there is one difference. Unlike the findOneAndUpdate() method, the updateOne() method does not return the matched document. Instead, it returns an object that contains details about the operation.

We will use the updateOne() method to update the document where the name is “Sergio Ramos”. Ramos plays for Real Madrid, not Barcelona. Let’s fix this.

1
2
3
4
5
6
7
8
9
10
11
12
router.route("/update").put(function(req, res) {
  myteam.updateOne({ name: "Sergio Ramos" }, { club: "Real Madrid" }, function(
    err,
    result
  ) {
    if (err) {
      res.send(err);
    } else {
      res.json(result);
    }
  });
});

Both the arguments are in the same way as we did in the findOneAndUpdate() method. Let’s execute this route.

Image from Gyazo

As mentioned earlier, it returns an object. The value of “nModified” is 1. This means, one document was updated.

updateMany()

Now, this method is different. The updateMany() method is used to update multiple documents. It updates all the documents that match the query. In the myteam collection, documents where the name is “Tony Kroos” and “Leroy Sane” states that their country is “France”. But both of them are from “Germany”. So we have more than one document to update and both of them have “France” as their values for the country field. Moreover, no other document has “France” as the value of the country field. So we can use the country field as the query.

1
2
3
4
5
6
7
8
9
10
11
12
router.route("/update").put(function(req, res) {
  myteam.updateMany({ country: "France" }, { country: "Germany" }, function(
    err,
    result
  ) {
    if (err) {
      res.send(err);
    } else {
      res.json(result);
    }
  });
});

Let’s execute this route using the postman tool.

Image from Gyazo

The updateMany() method also returns an object. The value “n” is 2 meaning, two documents were matched. The value of “nModified” is also 2, meaning, two documents were updated.

Conclusion

There is a lot when it comes to the Update operation in mongoose. There are other methods such as findByIdAndUpdate() and findOneAndReplace() that are also useful. But the methods we discussed above are the most important ones.

Pilot the ObjectRocket Platform Free!

Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.

Get Started

Keep in the know!

Subscribe to our emails and we’ll let you know what’s going on at ObjectRocket. We hate spam and make it easy to unsubscribe.