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.