MongoDB Find and Modify

Have a Database Problem? Speak with an Expert for Free
Get Started >>

Introduction

When you need to modify an existing document in MongoDB, there are times when you want a bit more control over the process than the update() method can offer. With a regular update(), by the time the document is located and modified, there may be another update operation occurring on the same document. In these situations, the findAndModify() method may be exactly what you need to ensure that no other thread modifies the specified document until it’s finished updating. This tutorial will provide an overview of the findAndModify() method and show an example of how to use MongoDB to find and modify a document.

Prerequisite

Before you proceed with this tutorial, be sure that MongoDB is installed and properly configured on your machine.

The overview

The MongoDB find and modify (findAndModify()) method will modify a single document that is located based on criteria defined by the user. If a matching record isn’t found in the database, a new document will be created if we set the upsert option to ‘true’.

By default, the returned document doesn’t reflect the updated content, but this functionality can be enabled with the new option. We’ll see how this option works later on in this article.

The findAndModify() Method Parameters

Let’s look at the parameters we can use with the findAndModify() method to better refine the results of our queries:

  • query – This field holds the selection criteria for the document we want to modify. The selectors are similar to those used with the find() method (db.collection.find()). The findAndModify() method selects a single document to modify even though its query may match many documents.
  • sort – This field helps define which document will be modified by the operation if the query selects multiple documents. The first document returned based on the specified sort order will be modified by the findAndModify() method.
  • new – If this argument is set to true, the method will return the modified version of the document instead of the original.
  • fields – This argument specifies the collections or set of fields to be returned.
  • upsert – If this argument set to ‘true’, the method will create a new document in the event that no document matches the defined query.

findAndModify() method Examples

Now that we’ve provided an overview of the findandModify() method and examined the parameters that can be used with it, let’s try to use MongoDB to find and modify a document. In this section, we’ll look at some examples of how to use the findAndModify() method.

Here’s the sample hotel document that we’ll be using for these examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
        "_id" : ObjectId("5e198ce4fcbb578f1a59b4c4"),
        "name" : "Agoda",
        "Hotel_id" : "163925",
        "address" : {
                "building" : "1021",
                "dayrate" : 300,
                "zipcode" : "1041"
        },
        "ratings" : 5,
        "rooms" : [
                "Standard Queen Room",
                "Superior Queen Room"
        ]
}
{
        "_id" : ObjectId("5e198db9fcbb578f1a59b4c5"),
        "name" : "Mediva",
        "Hotel_id" : "163940",
        "address" : {
                "building" : "370",
                "dayrate" : 350,
                "zipcode" : "1031"
        },
        "ratings" : 5,
        "rooms" : [
                "Standard King Room",
                "Superior Queen Room"
        ]
}

The query shown below will update an existing document within the hotel collection as long as a document matches the criteria:

1
2
3
4
5
db.hotel.findAndModify({
    query: { "name" : "Mediva" },
    sort: { Hotel_id: 1 },
    update: { $inc: { "ratings": -1 } }
});

Let’s take a closer look at this code and see what’s going on.

First, notice the results will be sorted in ascending order. If multiple documents meet the query criteria, the findAndModify() method will only select the first document for modification based on this sort order.

The update option uses the $inc parameter which indicates an increment; however, we provided a negative value, so the operation will actually decrement the value of ‘ratings’ by 1.

This method will return the original value of the document since we did not set the new parameter.

The output will look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
        "_id" : ObjectId("5e198db9fcbb578f1a59b4c5"),
        "name" : "Mediva",
        "Hotel_id" : "163940",
        "address" : {
                "building" : "370",
                "dayrate" : 350,
                "zipcode" : "1031"
        },
        "ratings" : 5,
        "rooms" : [
                "Standard King Room",
                "Superior Queen Room"
        ]
}

We can verify that the appropriate changes were made to the ratings by using the following command : db.hotel.find({Hotel_id:"163940"}).pretty();

The result should look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
        "_id" : ObjectId("5e198db9fcbb578f1a59b4c5"),
        "name" : "Mediva",
        "Hotel_id" : "163940",
        "address" : {
                "building" : "370",
                "dayrate" : 350,
                "zipcode" : "1031"
        },
        "ratings" : 4,
        "rooms" : [
                "Standard King Room",
                "Superior Queen Room"
        ]
}

We can see that the ratings value was indeed decreased by one.

Now let’s use the same query again, but this time the modified results will be returned after executing the query.

1
2
3
4
5
6
db.hotel.findAndModify({
    query: { "name" : "Mediva" },
    sort: { Hotel_id: 1 },
    update: { $inc: { "ratings": -1 } },
    new: true
});

The output should look like the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
        "_id" : ObjectId("5e198db9fcbb578f1a59b4c5"),
        "name" : "Mediva",
        "Hotel_id" : "163940",
        "address" : {
                "building" : "370",
                "dayrate" : 350,
                "zipcode" : "1031"
        },
        "ratings" : 3,
        "rooms" : [
                "Standard King Room",
                "Superior Queen Room"
        ]
}

Notice that the value of ratings was decreased once again by 1.

Conclusion

When you need to modify an existing MongoDB document and the update() method doesn’t quite fit your requirements, the findAndModify() method can be an effective alternative. In this article, we discussed the various parameters used in this method and showed some examples of how to use it. With our examples to use as a guide, you’ll be able to use MongoDB to find and modify documents in your own collections.

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.