MongoDB: How to update a field based on its current value (with examples)

Updated: February 3, 2024 By: Guest Contributor Post a comment

Introduction

MongoDB is a powerful NoSQL database often used for its flexibility and performance. Updating records in MongoDB, in specific updating a field based on its existing value, is a common operation, and there are several methods to achieve this. This tutorial will explore various ways in which you can update a document’s field based on the current value of that field, complete with examples ranging from basic to advanced.

Basic Update with $set

Before we jump into updating fields based on their current values, let’s review the basic update operation using the $set operator. Assume we have a collection named users containing user documents that look like this:

{
    "_id": ObjectId("507f191e810c19729de860ea"),
    "name": "John Doe",
    "age": 28
}

To simply change the age of a user you would use:

db.users.updateOne(
    { "name": "John Doe" },
    { "$set": { "age": 30 } }
);

This statement would set John Doe’s age to 30. Now let’s see how to increment the current age by 2:

Incrementing a Field

Using the $inc operator, we can update a field based on its current value. To increment John’s age by 2, we could write:

db.users.updateOne(
    { "name": "John Doe" },
    { "$inc": { "age": 2 } }
);

This update operation reads the current value of the age field and adds 2 to it, updating the document accordingly.

Conditionally Updating a Field

What if we want to update the age only if it’s below a certain threshold? That requires the combination of a query filter and the update:

db.users.updateOne(
    { "name": "John Doe", "age": { "$lt": 30 } },
    { "$set": { "age": 30 } }
);

In this instance, if John Doe is younger than 30, his age is set to 30. If he is 30 or older, the document is not updated.

Using $mul to Update a Field

If instead of adding a static number to a field, you want to multiply a field by a given number, you’d use the $mul operator. Suppose we want to double the age:

db.users.updateOne(
    { "name": "John Doe" },
    { "$mul": { "age": 2 } }
);

After this operation, if John’s initial age was 28, it would now be 56.

Advanced Updates Using Aggregation Pipeline

With the advent of MongoDB 4.2 and later versions, you can pass an aggregation pipeline to the updateOne() or updateMany() functions. This allows for complex computations and conditional updates based on the current value of the field.

Here’s an example where we cap the age at 50, but if the age is under 30, we increment by 10>:

db.users.updateOne(
    { "name": "John Doe" },
    [{
        "$set": {
            "age": {
                "$cond": {
                    "if": { "$lt": ["$age", 30] },
                    "then": { "$add": ["$age", 10] },
                    "else": { "$min": ["$age", 50] }
                }
            }
        }
    }]
);

This uses the $cond operator to determine whether to add 10 to the age or simply set it to 50, depending on the starting value of age.

Updating Fields Based on Other Fields

In certain cases, fields within the same document are dependent on each other. For example, suppose our users documents also have a birthdate and we want to set the age field based on the birthdate. Here’s an example using the $dateDiff operator available in MongoDB 5.0 and newer versions:

db.users.updateMany(
    {},
    [{
        "$set": {
            "age": {
                "$floor":  {
                    "$divide": [
                        { "$dateDiff": {
                            "startDate": "$birthdate",
                            "endDate": "$currentDate",
                            "unit": "year"
                        } },
                        1
                    ] }
                }
            }
        }
    }]
);

This pipeline updates the age of all users in the collection based on their birthdates. It calculates the difference in years between the current date and their birthdate and then sets the age accordingly.

Conclusion

The versatility of MongoDB’s update operations allows for precise manipulation of document fields. We’ve seen the capability of simple updates with operators like $set and $inc, as well as complex computations with the aggregation pipeline for conditional updates and inter-field dependencies. Use these powerful tools to ensure your data stays accurate and up-to-date.