Skip to main content

Update in MongoDB

In MongoDB, the modify operation is part of the CRUD (Create, Read, Update, Delete) operations and focuses on updating existing documents within a collection. You can modify single or multiple documents using various update operators. Below are some common methods and operators used for modifying data:

updateOne()​

Updates a single document that matches the query criteria.

db.collection.updateOne({ query }, { update })

updateMany()​

Updates all documents that match the query criteria.

db.collection.updateMany({ query }, { update })

replaceOne()​

Replaces a single document that matches the query criteria with a new document.

db.collection.replaceOne({ query }, { replacement })

findOneAndUpdate()​

Finds a single document that matches the query criteria and updates it, returning either the original or the updated document.

db.collection.findOneAndUpdate({ query }, { update }, { options })

Common Update Operators​

Field Update Operators​

  • $set: Sets the value of a field.
  • $unset: Removes a field.

In MongoDB, the $set and $unset operators are commonly used for updating documents. These operators allow you to modify specific fields within documents without affecting other existing fields. Here's how they work:

Using $set for Updating Fields​

The $set operator replaces the value of a field with the specified value. If the field does not exist, $set will add a new field with the specified value.

Syntax​

db.collection.updateOne(
{ <query conditions> },
{ $set: { <field1>: <value1>, <field2>: <value2>, ... } }
);

Example​

Suppose you have a document like this in a collection named users:

{
"_id": 1,
"name": "Alice",
"age": 30
}

To update the age field to 31:

db.users.updateOne(
{ _id: 1 },
{ $set: { age: 31 } }
);

The document will now look like this:

{
"_id": 1,
"name": "Alice",
"age": 31
}

Using $unset to Remove Fields​

The $unset operator removes the specified field from a document. If the field does not exist, $unset does nothing.

Syntax​

db.collection.updateOne(
{ <query conditions> },
{ $unset: { <field1>: "", <field2>: "", ... } }
);

Example​

Using the same document as before:

{
"_id": 1,
"name": "Alice",
"age": 31
}

To remove the age field:

db.users.updateOne(
{ _id: 1 },
{ $unset: { age: "" } }
);

The document will now look like this:

{
"_id": 1,
"name": "Alice"
}

Combining $set and $unset​

You can combine $set and $unset in a single update operation.

Example​

To update the name field to "Bob" and remove the age field:

db.users.updateOne(
{ _id: 1 },
{
$set: { name: "Bob" },
$unset: { age: "" }
}
);

The document will now look like this:

{
"_id": 1,
"name": "Bob"
}

Considerations​

  • Both $set and $unset are idempotent operations. Repeating them produces the same result.

  • These operators only affect the fields specified and leave the rest of the document unchanged.

Array Update Operators​

  • $push: Adds an element to an array.
  • $pop: Removes the first or last element from an array.
  • $pull: Removes all instances of a value from an array.

In MongoDB, the $push, $pop, and $pull operators are used to manipulate array fields within documents. These operators allow you to add, remove, and modify elements in an array field.

Using $push to Add Elements​

The $push operator appends a specified value to an array. If the array field does not exist, $push adds a new array field with the specified value as its first element.

Syntax​

db.collection.updateOne(
{ <query conditions> },
{ $push: { <array field>: <value> } }
);

Example​

Suppose you have a document like this:

{
"_id": 1,
"name": "Alice",
"hobbies": ["reading", "swimming"]
}

To add "cycling" to the hobbies array:

db.users.updateOne(
{ _id: 1 },
{ $push: { hobbies: "cycling" } }
);

The document will now look like this:

{
"_id": 1,
"name": "Alice",
"hobbies": ["reading", "swimming", "cycling"]
}

Using $pop to Remove Elements​

The $pop operator removes the first or last element of an array. Pass -1 to remove the first element and 1 to remove the last element.

Syntax​

db.collection.updateOne(
{ <query conditions> },
{ $pop: { <array field>: <-1 or 1> } }
);

Example​

Using the same document as before:

{
"_id": 1,
"name": "Alice",
"hobbies": ["reading", "swimming", "cycling"]
}

To remove the last element ("cycling") from the hobbies array:

db.users.updateOne(
{ _id: 1 },
{ $pop: { hobbies: 1 } }
);

The document will now look like this:

{
"_id": 1,
"name": "Alice",
"hobbies": ["reading", "swimming"]
}

Using $pull to Remove Specific Elements​

The $pull operator removes all instances of a value from an existing array.

Syntax​

db.collection.updateOne(
{ <query conditions> },
{ $pull: { <array field>: <value or condition> } }
);

Example​

Using the same document as before:

{
"_id": 1,
"name": "Alice",
"hobbies": ["reading", "swimming"]
}

To remove "reading" from the hobbies array:

db.users.updateOne(
{ _id: 1 },
{ $pull: { hobbies: "reading" } }
);

The document will now look like this:

{
"_id": 1,
"name": "Alice",
"hobbies": ["swimming"]
}

Considerations​

  • $push can also accept modifiers like $each to push multiple values, and $sort to keep the array sorted.

  • $pull can remove elements based on conditions, not just specific values.

  • $pop only removes the first or last element, and it doesn't work based on a condition or specific value.

Arithmetic Update Operators​

  • $inc: Increments a field by a specified value.
  • $mul: Multiplies a field by a specified value.

In MongoDB, the $inc and $mul operators are used to increment and multiply the value of a field, respectively. These operators are useful for updating numerical fields in a document without having to read the document, modify it in your application, and then write it back to the database.

Using $inc to Increment Fields​

The $inc operator increments a field by a specified value. If the field does not exist, $inc will create the field and set it to the specified value.

Syntax​

db.collection.updateOne(
{ <query conditions> },
{ $inc: { <field1>: <amount1>, <field2>: <amount2>, ... } }
);

Example​

Suppose you have a document like this:

{
"_id": 1,
"name": "Alice",
"age": 30,
"score": 50
}

To increment the age by 1 and the score by 10:

db.users.updateOne(
{ _id: 1 },
{ $inc: { age: 1, score: 10 } }
);

The document will now look like this:

{
"_id": 1,
"name": "Alice",
"age": 31,
"score": 60
}

Using $mul to Multiply Fields​

The $mul operator multiplies the value of a field by a specified number. If the field does not exist, $mul will create the field and set it to 0.

Syntax​

db.collection.updateOne(
{ <query conditions> },
{ $mul: { <field1>: <number1>, <field2>: <number2>, ... } }
);

Example​

Using the same document as before:

{
"_id": 1,
"name": "Alice",
"age": 31,
"score": 60
}

To multiply the age by 2 and the score by 3:

db.users.updateOne(
{ _id: 1 },
{ $mul: { age: 2, score: 3 } }
);

The document will now look like this:

{
"_id": 1,
"name": "Alice",
"age": 62,
"score": 180
}

Considerations​

  • Both $inc and $mul are atomic operations, ensuring that the update is thread-safe.

  • These operators work only on numerical fields. Attempting to use them on non-numeric fields will result in an error.

  • You can use negative numbers with $inc to decrement a field, and you can use fractions with $mul to effectively divide a field.

Bitwise Update Operators​

In MongoDB, the $bit operator is used for bitwise updates of integer fields. The operator supports bitwise AND, OR, and XOR (XOR is available starting from MongoDB 2.6). The $bit operator is useful when you need to change specific bits of an integer field without affecting the others.

Syntax​

The general syntax for using the $bit operator is as follows:

db.collection.updateOne(
{ <query conditions> },
{ $bit: { <field>: { <operator>: <value> } } }
);

Here, <operator> can be and, or, or xor, and <value> is the integer value to apply the bitwise operation with.

Using $bit for Bitwise AND​

The and operation performs a bitwise AND between the current value of the field and the specified value.

Example​

Suppose you have a document with a field flags set to 5 (binary 0101):

db.users.updateOne(
{ _id: 1 },
{ $bit: { flags: { and: 3 } } } // 3 in binary is 0011
);

The flags field will be updated to 1 (binary 0001), which is the result of 0101 AND 0011.

Using $bit for Bitwise OR​

The or operation performs a bitwise OR between the current value of the field and the specified value.

Example​

Suppose you have a document with a field flags set to 5 (binary 0101):

db.users.updateOne(
{ _id: 1 },
{ $bit: { flags: { or: 2 } } } // 2 in binary is 0010
);

The flags field will be updated to 7 (binary 0111), which is the result of 0101 OR 0010.

Using $bit for Bitwise XOR​

The xor operation performs a bitwise XOR between the current value of the field and the specified value.

Example​

Suppose you have a document with a field flags set to 5 (binary 0101):

db.users.updateOne(
{ _id: 1 },
{ $bit: { flags: { xor: 3 } } } // 3 in binary is 0011
);

The flags field will be updated to 6 (binary 0110), which is the result of 0101 XOR 0011.

Considerations​

  • The $bit operator only works on integer fields. Applying it to non-integer fields will result in an error.

  • The $bit operator is an atomic operation, ensuring that the update is thread-safe.

  • You can combine multiple bitwise operations in a single update query.

Other Update Operators​

  • $rename: Renames a field.
  • $min: Updates a field to the minimum of the current and specified values.
  • $max: Updates a field to the maximum of the current and specified values.

In MongoDB, the $rename, $min, and $max operators are used to rename fields, and to update fields based on minimum or maximum value comparisons, respectively. These operators provide a way to perform specific types of updates atomically and efficiently.

Using $rename to Rename Fields​

The $rename operator renames a field in a document. If the new field name already exists, the operator will overwrite the existing field's value.

Syntax​

db.collection.updateOne(
{ <query conditions> },
{ $rename: { <old_field_name>: <new_field_name> } }
);

Example​

Suppose you have a document like this:

{
"_id": 1,
"name": "Alice",
"age": 30
}

To rename the age field to years:

db.users.updateOne(
{ _id: 1 },
{ $rename: { "age": "years" } }
);

The document will now look like this:

{
"_id": 1,
"name": "Alice",
"years": 30
}

Using $min to Update Based on Minimum Value​

The $min operator updates the value of a field to a specified value if the specified value is less than the current value of the field.

Syntax​

db.collection.updateOne(
{ <query conditions> },
{ $min: { <field>: <value> } }
);

Example​

Suppose you have a document like this:

{
"_id": 1,
"name": "Alice",
"score": 50
}

To update the score field to 40 only if 40 is less than the current score:

db.users.updateOne(
{ _id: 1 },
{ $min: { "score": 40 } }
);

The document will now look like this:

{
"_id": 1,
"name": "Alice",
"score": 40
}

Using $max to Update Based on Maximum Value​

The $max operator updates the value of a field to a specified value if the specified value is greater than the current value of the field.

Syntax​

db.collection.updateOne(
{ <query conditions> },
{ $max: { <field>: <value> } }
);

Example​

Suppose you have a document like this:

{
"_id": 1,
"name": "Alice",
"score": 40
}

To update the score field to 50 only if 50 is greater than the current score:

db.users.updateOne(
{ _id: 1 },
{ $max: { "score": 50 } }
);

The document will now look like this:

{
"_id": 1,
"name": "Alice",
"score": 50
}

Considerations​

  • The $rename operator will remove the old field name and its value from the document.

  • $min and $max work with numerical as well as date fields.

  • These operators are atomic, ensuring that the update is thread-safe.

Options for Modify Operations​

  • upsert: Creates a new document if no documents match the query.
  • returnNewDocument: Returns the updated document rather than the original.

In MongoDB, the upsert and returnNewDocument options are used to control the behavior of update and find-and-modify operations. These options offer flexibility in how documents are updated or returned.

Using upsert for Inserting or Updating​

The upsert option stands for "update or insert." When you perform an update operation with upsert: true, MongoDB will update the document if it exists. If the document does not exist, MongoDB will insert a new document.

Syntax for updateOne​

db.collection.updateOne(
{ <query conditions> },
{ <update operations> },
{ upsert: true }
);

Example​

Suppose you want to set the score field to 100 for a user with _id: 1. If the user doesn't exist, you want to create a new document.

db.users.updateOne(
{ _id: 1 },
{ $set: { score: 100 } },
{ upsert: true }
);

If a document with _id: 1 exists, its score field will be set to 100. If the document doesn't exist, a new document with _id: 1 and score: 100 will be inserted.

Using returnNewDocument with findOneAndUpdate​

The returnNewDocument option is used with the findOneAndUpdate method to control which version of the document is returned: the original document or the updated document.

Syntax​

db.collection.findOneAndUpdate(
{ <query conditions> },
{ <update operations> },
{ returnNewDocument: true }
);

Example​

Suppose you have a document like this:

{
"_id": 1,
"name": "Alice",
"score": 50
}

You want to increment the score by 10 and return the updated document.

const updatedDoc = db.users.findOneAndUpdate(
{ _id: 1 },
{ $inc: { score: 10 } },
{ returnNewDocument: true }
);

With returnNewDocument: true, the updatedDoc will contain the updated document:

{
"_id": 1,
"name": "Alice",
"score": 60
}

Considerations​

  • The upsert option can be used with updateOne, updateMany, and findOneAndUpdate methods.

  • The returnNewDocument option is specific to findOneAndUpdate and its variants (findOneAndReplace, findOneAndDelete).

  • These options are atomic, ensuring that the operations are thread-safe.