MongoDB Update Document Tutorial

In this MongoDB tutorial we learn about the third CRUD operation, updating documents.

We cover how to implicitly and explicitly update and replace documents as well as upserting.

How to update existing documents

To update an existing document in a collection we use the db.collection.update() method.

This method takes three arguments.

  • Filter to choose which values to update
  • Replacement to update the values
  • Options to modify the operation (optional)
Syntax:
db.collection.update(filter, replacement, options)

As an example, let’s consider a simple collection with the following two documents.

Example:
db.users.insert([
    { "name" : "John" },
    { "name" : "Jane" }
])

Let’s say that “John” changes his username to “Jack”. We can update this information directly with the .update() method and $set meta expression.

  • For the selection criteria we need to specify the key:value pair that we want to update.
  • For the updated data we need to specify the $set meta expression followed by the new data.

MongoDB will find the correct document to update based on the filter criteria. If the data was found, it will replace the data we specify with the new data we provide with the $set meta expression.

Example:
db.users.update(
    { "name" : "John" },
    {
        $set : { "name" : "Jack" }
    }
)

If the operation was successful, the terminal will return the number of documents updated.

Output:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

We can now do a simple read query to see if it worked.

Example:
db.users.find()
Output:
{ "_id" : ObjectId("5fabf085eaeb0de0612c56ae"), "name" : "Jack" }
{ "_id" : ObjectId("5fabf085eaeb0de0612c56af"), "name" : "Jane" }

Great, the update was successful and the name now shows “Jack” instead of “John”.

By default, the update() method will only update single values. If we want to be able to change multiple values at once, we need to set the third optional parameter multi to true.

Syntax:
db.collection.update(selection_criteria, updated_data, { multi : true })

How to replace an existing document with a new one

We can replace an existing document with a new one, based on a filter, with the db.collection.replaceOne() method.

This method takes three arguments.

  • Filter to choose which document to replace
  • Replacement to replace the document
  • Options to modify the replacement operation (optional)
Syntax:
db.collection.replaceOne(filter, replacement, options)

As an example, let’s consider that we want to replace the username “Jack” with “John”.

Example:
db.users.replaceOne(
    { "name" : "Jack" },
    { "name" : "John" }
)

If the replacement operation was successful, the terminal will return the following.

Output:
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

Let’s do a quick read query to see if it worked.

Example:
db.users.find()
Output:
{ "_id" : ObjectId("5fabf085eaeb0de0612c56ae"), "name" : "John" }
{ "_id" : ObjectId("5fabf085eaeb0de0612c56af"), "name" : "Jane" }

Great, the replacement was successful and the name now shows “John” instead of “Jack”.

Upsert

Upsert is an operation that will update or replace a document only if the document doesn’t already exist.

We set upsert : true on the third Options parameter of the update() and replaceOne() methods.

Syntax:
db.collection.update(filter, replacement, { upsert : true })

Let’s consider that we want to update the document with the name “Jacob” to the name “Jack”, but “Jacob” doesn’t exist.

Example:
db.users.update(
    { "name" : "Jacob" },
    { "name" : "Jack"  },
    { upsert : true }
)

If the update was successful, the terminal will return the following.

Output:
WriteResult({
    "nMatched" : 0,
    "nUpserted" : 1,
    "nModified" : 0,
    "_id" : ObjectId("5fabfbb580accfbdb6ff1c56")
})

The “nUpserted” key shows a value of 1, which means that 1 document with the new data has been inserted because it didn’t exist.

Let’s do a quick read query to see what happened.

Example:
db.users.find()
Output:
{ "_id" : ObjectId("5fabf085eaeb0de0612c56ae"), "name" : "John" }
{ "_id" : ObjectId("5fabf085eaeb0de0612c56af"), "name" : "Jane" }
{ "_id" : ObjectId("5fabfbb580accfbdb6ff1c56"), "name" : "Jack" }

The extra document was added because “Jacob” didn’t exist.

If we upsert on a document that already exists, it will simply update the first record that matches the filter.

How to explicitly update only a single document

To explicitly update only a single document we use the db.collection.updateOne() method. This method will only update the first document it finds through the filter.

This method takes three arguments.

  • Filter to choose which value to update
  • Replacement to update the value with
  • Options to modify the operation (optional)
Syntax:
db.collection.updateOne(filter, replacement, options)

MongoDB will find the correct document to update based on the filter criteria. If the data was found, it will replace the data we specify with the new data we provide with the $set meta expression.

Example:
db.users.updateOne(
    { "name" : "John" },
    {
        $set : { "name" : "Jack" }
    }
)

If the operation was successful, the terminal will return the number of documents updated.

Output:
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

We can now do a simple read query to see if it worked.

Example:
db.users.find()
Output:
{ "_id" : ObjectId("5fabf085eaeb0de0612c56ae"), "name" : "Jack" }
{ "_id" : ObjectId("5fabf085eaeb0de0612c56af"), "name" : "Jane" }

Great, the update was successful and the name now shows “Jack” instead of “John”.

How to explicitly update multiple documents

If we want to update more than one document at a time, we can use the dedicated db.collection.updateMany() method.

This method takes three arguments.

  • Filter to choose which values to update
  • Replacement to update the values with
  • Options to modify the operation (optional)
Syntax:
db.collection.updateMany(filter, replacement, options)

As an example, let’s consider that we have some exam results from students and we want to update the status of everyone who passed.

Example:
db.results.insert([
    { "name": "John", "score": 53, "passed": false },
    { "name": "Jane", "score": 87, "passed": false },
    { "name": "Jack", "score": 76, "passed": false },
    { "name": "Jill", "score": 59, "passed": false }
])

Students who have a score greater than or equal to 60 passes, the others fail.

Example:
db.results.updateMany(
    { "score" : {$gte : 60} },
    {
        $set : { "passed" : true }
    }
)

If the update operation succeeds, the number of documents updated will be shown.

Output:
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }

We can now do a simple read query to see if it worked.

Example:
db.results.find()
Output:
{ "_id" : ObjectId("5fac31a5408d3777a4bfc6a6"), "name" : "John", "score" : 53, "passed" : false }
{ "_id" : ObjectId("5fac31a5408d3777a4bfc6a7"), "name" : "Jane", "score" : 87, "passed" : true }
{ "_id" : ObjectId("5fac31a5408d3777a4bfc6a8"), "name" : "Jack", "score" : 76, "passed" : true }
{ "_id" : ObjectId("5fac31a5408d3777a4bfc6a9"), "name" : "Jill", "score" : 59, "passed" : false }

Great, the update was successful and the two students with scores above 60 has been updated.