The MongoDB Update Command

Introduction

This article shows how to update one or multiple existing documents in a MongoDB database.

The following instructions assumes that there is a collection "products" which contains documents with the same structure like this one:

{
  "_id" : ObjectId("57cc58333d496dc219c09c2c"),
  "firstname" : "Max",
  "lastname" : "Mustermann",
  "email" : "m.mustermann@example.com",
  "password" : "d9729feb74992cc3482b350163a1a010",
  "last_login" : "2015-01-07",
  "note" : "Always pays in time, very good customer!",
  "address" :
  {
    "country" : "Germany",
    "street" : "Beispielstrasse 64",
    "zip" : "62717"
  }
}

In general, the MongoDB update command looks like this:

db.collection-name.update(document selector, updated data, [update options])

  • The collection name specifies the collection in which the document(s) to update is (are) located.
  • The document selector describes which document(s) from the collection should be updated. The same query statements as in the
  • MongoDB find function can be used.
  • The updated data describes how the document(s) should be modified.

Replace an existing document entirely

The simplest use case of the MongoDB update command is to replace a single existing document entirely.

For example, if we want to replace the above example document representing a customer we can execute the following command in a MongoDB client:

> db.customers.update(
  {"_id": ObjectId("57cc58333d496dc219c09c2c")},

  {
    "firstname" : "Peter",
    "lastname" : "Mustermann",
    "email" : "p.mustermann@example.com",
    "password" : "d9729feb74992cc3482b350163a1a010",
    "last_login" : "2015-01-07",
    "note" : "Always pays in time, very good customer!",
    "address" :
    {
      "country" : "Germany",
      "street" : "Beispielstrasse 64",
      "zip" : "62717"
    }
  }
);

In this update command the internal object ID is used as document selector to identify the document which should be replaced.

The second parameter of the update statement above is the new document that will override the old one.

Note: Although only the first name and the email fields changes in the customer document, each field must be specified in this update command because the whole document is replaced. Values that are not specified in this update command will not be available in the document anymore. Only the '_id' field must not be specified since it's an internal field maintained by MongoDB.

As a result of the update command you should see the following output indicating that one document has been updated.

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

If you can't or don't want to identify the document which you would like to replace with the internal ID you can also use any other field. The following update statement will replace the document which current firstname field is "Max".

> db.customers.update(
  {"firstname": "Max"},

  {
    "firstname" : "Peter",
    "lastname" : "Mustermann",
    "email" : "p.mustermann@example.com",
    "password" : "d9729feb74992cc3482b350163a1a010",
    "last_login" : "2015-01-07",
    "note" : "Always pays in time, very good customer!",
    "address" :
    {
      "country" : "Germany",
      "street" : "Beispielstrasse 64",
      "zip" : "62717"
    }
  }
);

The result of this update looks the same like the result of the previous update.

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

Note: Even if there is more then one document which firstname field is "Max" only the first document will be updated. The other matching documents won't be modified. For more information how to update all matching documents see chapter "Update fields of multiple documents" .

Update specific fields of a single document

Instead of replacing the whole document it is mostly required to just modify one or some fields of a document and keep the other fields untouched. For this use case MongoDB provides different operators that can be specified in the update command.

Replace field values of a document using the $set operator

If only one field of a document should be updated the "$set" operator can be used. The set operator will override the old value of a specified field.

The following update command finds the first document which firstname field is equal "Max" and updates (sets) the lastname field to "Maier".

> db.customers.update(
  {"firstname": "Max"},
  {
    $set: {
      "lastname": "Maier"
    }
  }
);

Note: Even if there is more then one document which firstname field is "Max" only the first document will be updated. The other matching documents won't be modified. For more information how to update all matching documents see chapter "Update fields of multiple documents" .

To update multiple fields of a document the command looks like this:

> db.customers.update(
  {"firstname": "Max"},
  {
    $set: {
      "lastname": "Maier",
      "email": "p.maier@example.com"
    }
  }
);

To update a field that is nested in the JSON structure the following command can be used:

> db.customers.update(
  {"firstname": "Max"},
  {
    $set: {
      "lastname": "Maier",
      "address.street": "another street"
    }
  }
);

Increment numeric field values of a document using the $inc operator

For numeric field values it is possible to modify the value regarding their old value. The MongoDB $inc operator is intended to be used to fulfil this purpose. The following example will increase the zip code of a customer by one. When the zip code is 94101 it will be 94102 after the update.

> db.customers.update(
  {_id: ObjectId("57dcf6af1eb6b4f388a7add5")},
  {$inc: {"address.zip": 1 }}
);

Decreasing values is also possible with the $inc operator. To do this just specify a negative value. The following command will decrease the value by 5.

> db.customers.update(
  {_id: ObjectId("57dcf6af1eb6b4f388a7add5")},
  {$inc: {"address.zip": -5 }}
);

Note: Even if there is more then one document that matches the query selector only the first document will be updated. The other matching documents won't be modified. For more information how to update all matching documents see chapter "Update fields of multiple documents" .

Update specific fields of multiple documents

So far all MongoDB update queries only updated/replaced exactly one document even though the selector matched multiple documents. To update all matching documents an addional option must be set:

> db.customers.update(
  {"firstname": "Max"},
  {
    $set: {
      "email": "p.maier@example.com"
    }
  },
  {"multi": true}
);

This command returns the following result:

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

In this example nMatched shows that two documents have been found by the document selector query but nModified shows that only one document have been updated by the update command. nModified is smaller then nMatched in case the update command sets the fields of some document to its current values. In other words: when the update operation doesn't change any field of some documents.