db.collection.update()
Definition
db.collection.update(query, update, options)
Important
mongo Shell Method
This page documents the
mongo
shell method, and does not refer to the MongoDB Node.js driver (or any other driver) method. For corresponding MongoDB driver API, refer to your specific MongoDB driver documentation instead.Modifies an existing document or documents in a collection. The method can modify specific fields of an existing document or documents or replace an existing document entirely, depending on the update parameter.
By default, the
db.collection.update()
method updates a single document. Include the option multi: true to update all documents that match the query criteria.
Compatibility
You can use db.collection.update()
for deployments hosted in the following
environments:
MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud
MongoDB Enterprise: The subscription-based, self-managed version of MongoDB
MongoDB Community: The source-available, free-to-use, and self-managed version of MongoDB
To learn how to update documents hosted in MongoDB Atlas by using the Atlas UI, see Create, View, Update, and Delete Documents.
Syntax
The db.collection.update()
method has the following form:
db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document>, collation: <document>, arrayFilters: [ <filterdocument1>, ... ], hint: <document|string> // Available starting in MongoDB 4.2 } )
Parameters
The db.collection.update()
method takes the following
parameters:
Parameter | Type | Description | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
document | The selection criteria for the update. The same query
selectors as in the When you execute an | |||||||||
document or pipeline | The modifications to apply. Can be one of the following:
For details and examples, see Examples. | |||||||||
boolean | Optional. When
If both To avoid multiple upserts, ensure that the
Defaults to | |||||||||
boolean | Optional. If set to | |||||||||
document | Optional. A document expressing the write concern. Omit to use the default write
concern Do not explicitly set the write concern for the operation if run in a transaction. To use write concern with transactions, see Transactions and Write Concern. For an example using | |||||||||
document | Optional. Collation allows users to specify language-specific rules for string comparison, such as rules for lettercase and accent marks. For an example using New in version 3.4. | |||||||||
array | Optional. An array of filter documents that determine which array elements to modify for an update operation on an array field. In the update document, use the
NoteYou cannot have an array filter document for an identifier if the identifier is not included in the update document. For examples, see Specify New in version 3.6. | |||||||||
Document or string | Optional. A document or string that specifies the index to use to support the query predicate. The option can take an index specification document or the index name string. If you specify an index that does not exist, the operation errors. For an example, see Specify New in version 4.2. |
Returns
The method returns a WriteResult document that contains the status of the operation.
Access Control
On deployments running with authorization
, the
user must have access that includes the following privileges:
update
action on the specified collection(s).find
action on the specified collection(s).insert
action on the specified collection(s) if the operation results in an upsert.
The built-in role readWrite
provides the required
privileges.
Behavior
Using $expr
in an Update with Upsert

Attempting to use the $expr
operator with the upsert flag set to true
will generate an error.
Sharded Collections
To use db.collection.update()
with multi: false
on a
sharded collection, you must include an exact match on the _id
field or target a single shard (such as by including the shard key).
When the db.collection.update()
performs update operations
(and not document replacement operations),
db.collection.update()
can target multiple shards.
Tip
See also:
Replace Document Operations on a Sharded Collection
Starting in MongoDB 4.2, replace document operations attempt to target a single shard, first by using the query filter. If the operation cannot target a single shard by the query filter, it then attempts to target by the replacement document.
In earlier versions, the operation attempts to target using the replacement document.
upsert
on a Sharded Collection
For a db.collection.update()
operation that includes
upsert: true and is on a sharded collection, you
must include the full shard key in the filter
:
For an update operation.
For a replace document operation (starting in MongoDB 4.2).
However, starting in version 4.4, documents in a sharded collection can be
missing the shard key fields. To target a
document that is missing the shard key, you can use the null
equality match in conjunction with another filter condition
(such as on the _id
field). For example:
{ _id: <value>, <shardkeyfield>: null } // _id of the document missing shard key
Shard Key Modification
Starting in MongoDB 4.2, you can update a document's shard key value
unless the shard key field is the immutable _id
field. Before
MongoDB 4.2, a document's shard key field value is immutable.
To modify the existing shard key value with
db.collection.update()
:
You must run on a
mongos
. Do not issue the operation directly on the shard.You must run either in a transaction or as a retryable write.
You must specify
multi: false
.You must include an equality query filter on the full shard key.
Tip
Since a missing key value is returned as part of a null equality
match, to avoid updating a null-valued key, include additional
query conditions (such as on the _id
field) as appropriate.
See also upsert
on a Sharded Collection.
Missing Shard Key
Starting in version 4.4, documents in a sharded collection can be
missing the shard key fields. To use
db.collection.update()
to set the document's
missing shard key, you must run on a
mongos
. Do not issue the operation directly on
the shard.
In addition, the following requirements also apply:
Task | Requirements |
---|---|
To set to null |
|
To set to a non- null value |
|
Tip
Since a missing key value is returned as part of a null equality
match, to avoid updating a null-valued key, include additional
query conditions (such as on the _id
field) as appropriate.
See also:
Transactions
db.collection.update()
can be used inside multi-document transactions.
Important
In most cases, multi-document transaction incurs a greater performance cost over single document writes, and the availability of multi-document transactions should not be a replacement for effective schema design. For many scenarios, the denormalized data model (embedded documents and arrays) will continue to be optimal for your data and use cases. That is, for many scenarios, modeling your data appropriately will minimize the need for multi-document transactions.
For additional transactions usage considerations (such as runtime limit and oplog size limit), see also Production Considerations.
Upsert within Transactions
Starting in MongoDB 4.4 with feature compatibility version
(fcv) "4.4"
, you can create collections and indexes
inside a multi-document transaction if the transaction is
not a cross-shard write transaction.
As such, for the feature compatibility version (fcv) is "4.4"
or greater, db.collection.update()
with upsert:
true
can be run against an existing collection or a non-existing
collection. If run against a non-existing collection, the operation
creates the collection.
If the feature compatibility version (fcv) is
"4.2"
or less, the operation must be against an existing
collection.
Tip
Write Concerns and Transactions
Do not explicitly set the write concern for the operation if run in a transaction. To use write concern with transactions, see Transactions and Write Concern.
Examples
The following tabs showcase a variety of common
update()
operations.
From the mongo
shell, create a books
collection which
contains the following documents. This command first removes all
previously existing documents from the books
collection:
db.books.remove({}); db.books.insertMany([ { "_id" : 1, "item" : "TBD", "stock" : 0, "info" : { "publisher" : "1111", "pages" : 430 }, "tags" : [ "technology", "computer" ], "ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "lmn", "rating" : 5 } ], "reorder" : false }, { "_id" : 2, "item" : "XYZ123", "stock" : 15, "info" : { "publisher" : "5555", "pages" : 150 }, "tags" : [ ], "ratings" : [ { "by" : "xyz", "rating" : 5 } ], "reorder" : false } ]);
Insert a New Document if No Match Exists (Upsert
)
When you specify the option upsert: true:
If document(s) match the query criteria,
db.collection.update()
performs an update.If no document matches the query criteria,
db.collection.update()
inserts a single document.Note
If multiple, identical upserts are issued at roughly the same time, it is possible for
update()
used with upsert: true to create duplicate documents. See Upsert with Unique Index for more information.
If you specify upsert: true
on a sharded collection, you must
include the full shard key in the filter
. For additional
db.collection.update()
behavior on a sharded collection, see
Sharded Collections.
The following tabs showcase a variety of uses of the upsert
modifier
with update()
.
Upsert with Unique Index
When using the upsert: true option with the update()
method, and not using a unique index on the query field(s), multiple
instances of a update()
operation with similar query
field(s) could result in duplicate documents being inserted in
certain circumstances.
Consider an example where no document with the name Andy
exists
and multiple clients issue the following command at roughly the same
time:
db.people.update( { name: "Andy" }, { $inc: { score: 1 } }, { upsert: true, multi: true } )
If all update()
operations finish the query phase
before any client successfully inserts data, and there is no
unique index on the name
field, each
update()
operation may result in an insert, creating multiple
documents with name: Andy
.
To ensure that only one such document is created, and the other
update()
operations update this new document instead, create a
unique index on the name
field. This
guarantees that only one document with name: Andy
is permitted
in the collection.
With this unique index in place, the multiple update()
operations
now exhibit the following behavior:
Exactly one
update()
operation will successfully insert a new document.All other
update()
operations will update the newly-inserted document, incrementing thescore
value.
Tip
See also:
Update with Aggregation Pipeline
Starting in MongoDB 4.2, the db.collection.update()
method
can accept an aggregation pipeline [ <stage1>, <stage2>, ... ]
that
specifies the modifications to perform. The pipeline can consist of
the following stages:
$addFields
and its alias$set
$replaceRoot
and its alias$replaceWith
.
Using the aggregation pipeline allows for a more expressive update statement, such as expressing conditional updates based on current field values or updating one field using the value of another field(s).
Modify a Field Using the Values of the Other Fields in the Document
Create a students
collection with the following documents:
db.students.insertMany( [ { "_id" : 1, "student" : "Skye", "points" : 75, "commentsSemester1" : "great at math", "commentsSemester2" : "loses temper", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }, { "_id" : 2, "students" : "Elizabeth", "points" : 60, "commentsSemester1" : "well behaved", "commentsSemester2" : "needs improvement", "lastUpdate" : ISODate("2019-01-01T00:00:00Z") } ] )
Assume that instead of separate commentsSemester1
and commentsSemester2
fields, you want to gather these into a new comments
field. The following
update operation uses an aggregation pipeline to:
add the new
comments
field and set thelastUpdate
field.remove the
commentsSemester1
andcommentsSemester2
fields for all documents in the collection.
db.members.update( { }, [ { $set: { comments: [ "$commentsSemester1", "$commentsSemester2" ], lastUpdate: "$$NOW" } }, { $unset: [ "commentsSemester1", "commentsSemester2" ] } ], { multi: true } )
Note
- First Stage
The
$set
stage:creates a new array field
comments
whose elements are the current content of thecommentsSemester1
andcommentsSemester2
fields andsets the field
lastUpdate
to the value of the aggregation variableNOW
. The aggregation variableNOW
resolves to the current datetime value and remains the same throughout the pipeline. To access aggregation variables, prefix the variable with double dollar signs$$
and enclose in quotes.
- Second Stage
- The
$unset
stage removes thecommentsSemester1
andcommentsSemester2
fields.
After the command, the collection contains the following documents:
{ "_id" : 1, "student" : "Skye", "status" : "Modified", "points" : 75, "lastUpdate" : ISODate("2020-01-23T05:11:45.784Z"), "comments" : [ "great at math", "loses temper" ] } { "_id" : 2, "student" : "Elizabeth", "status" : "Modified", "points" : 60, "lastUpdate" : ISODate("2020-01-23T05:11:45.784Z"), "comments" : [ "well behaved", "needs improvement" ] }
Tip
See also:
Perform Conditional Updates Based on Current Field Values
Create a students3
collection with the following documents:
db.students3.insert([ { "_id" : 1, "tests" : [ 95, 92, 90 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }, { "_id" : 2, "tests" : [ 94, 88, 90 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") }, { "_id" : 3, "tests" : [ 70, 75, 82 ], "lastUpdate" : ISODate("2019-01-01T00:00:00Z") } ]);
Using an aggregation pipeline, you can update the documents with the calculated grade average and letter grade.
db.students3.update( { }, [ { $set: { average : { $trunc: [ { $avg: "$tests" }, 0 ] }, lastUpdate: "$$NOW" } }, { $set: { grade: { $switch: { branches: [ { case: { $gte: [ "$average", 90 ] }, then: "A" }, { case: { $gte: [ "$average", 80 ] }, then: "B" }, { case: { $gte: [ "$average", 70 ] }, then: "C" }, { case: { $gte: [ "$average", 60 ] }, then: "D" } ], default: "F" } } } } ], { multi: true } )
Note
- First Stage
The
$set
stage:calculates a new field
average
based on the average of thetests
field. See$avg
for more information on the$avg
aggregation operator and$trunc
for more information on the$trunc
truncate aggregation operator.sets the field
lastUpdate
to the value of the aggregation variableNOW
. The aggregation variableNOW
resolves to the current datetime value and remains the same throughout the pipeline. To access aggregation variables, prefix the variable with double dollar signs$$
and enclose in quotes.
- Second Stage
- The
$set
stage calculates a new fieldgrade
based on theaverage
field calculated in the previous stage. See$switch
for more information on the$switch
aggregation operator.
After the command, the collection contains the following documents:
{ "_id" : 1, "tests" : [ 95, 92, 90 ], "lastUpdate" : ISODate("2020-01-24T17:29:35.340Z"), "average" : 92, "grade" : "A" } { "_id" : 2, "tests" : [ 94, 88, 90 ], "lastUpdate" : ISODate("2020-01-24T17:29:35.340Z"), "average" : 90, "grade" : "A" } { "_id" : 3, "tests" : [ 70, 75, 82 ], "lastUpdate" : ISODate("2020-01-24T17:29:35.340Z"), "average" : 75, "grade" : "C" }
Tip
See also:
Specify arrayFilters
for Array Update Operations
In the update document, use the $[<identifier>]
filtered
positional operator to define an identifier, which you then reference
in the array filter documents. You cannot have an array filter
document for an identifier if the identifier is not included in the
update document.
Note
The <identifier>
must begin with a lowercase letter and
contain only alphanumeric characters.
You can include the same identifier multiple times in the update
document; however, for each distinct identifier ($[identifier]
)
in the update document, you must specify exactly one
corresponding array filter document. That is, you cannot specify
multiple array filter documents for the same identifier. For
example, if the update statement includes the identifier x
(possibly multiple times), you cannot specify the following for
arrayFilters
that includes 2 separate filter documents for x
:
// INVALID [ { "x.a": { $gt: 85 } }, { "x.b": { $gt: 80 } } ]
However, you can specify compound conditions on the same identifier in a single filter document, such as in the following examples:
// Example 1 [ { $or: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] } ] // Example 2 [ { $and: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] } ] // Example 3 [ { "x.a": { $gt: 85 }, "x.b": { $gt: 80 } } ]
arrayFilters
is not available for updates that use an
aggregation pipeline.
Update Elements Match arrayFilters
Criteria
To update all array elements which match a specified criteria, use the arrayFilters parameter.
From the mongo
shell, create a students
collection with the following documents:
db.students.insertMany([ { "_id" : 1, "grades" : [ 95, 92, 90 ] }, { "_id" : 2, "grades" : [ 98, 100, 102 ] }, { "_id" : 3, "grades" : [ 95, 110, 100 ] } ])
To update all elements that are greater than or equal to 100
in the
grades
array, use the filtered positional operator
$[<identifier>]
with the arrayFilters
option:
db.students.update( { grades: { $gte: 100 } }, { $set: { "grades.$[element]" : 100 } }, { multi: true, arrayFilters: [ { "element": { $gte: 100 } } ] } )
After the operation, the collection contains the following documents:
{ "_id" : 1, "grades" : [ 95, 92, 90 ] } { "_id" : 2, "grades" : [ 98, 100, 100 ] } { "_id" : 3, "grades" : [ 95, 100, 100 ] }
Update Specific Elements of an Array of Documents
You can also use the arrayFilters parameter to update specific document fields within an array of documents.
From the mongo
shell, create a students2
collection with the following documents:
db.students2.insertMany([ { "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 90, "std" : 4 }, { "grade" : 85, "mean" : 85, "std" : 6 } ] }, { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 75, "std" : 6 }, { "grade" : 87, "mean" : 90, "std" : 3 }, { "grade" : 85, "mean" : 85, "std" : 4 } ] } ])
To modify the value of the mean
field for all elements in the
grades
array where the grade is greater than or equal to 85
,
use the filtered positional operator $[<identifier>]
with
the arrayFilters
:
db.students2.update( { }, { $set: { "grades.$[elem].mean" : 100 } }, { multi: true, arrayFilters: [ { "elem.grade": { $gte: 85 } } ] } )
After the operation, the collection has the following documents:
{ "_id" : 1, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 6 }, { "grade" : 85, "mean" : 100, "std" : 4 }, { "grade" : 85, "mean" : 100, "std" : 6 } ] } { "_id" : 2, "grades" : [ { "grade" : 90, "mean" : 100, "std" : 6 }, { "grade" : 87, "mean" : 100, "std" : 3 }, { "grade" : 85, "mean" : 100, "std" : 4 } ] }
Specify hint
for Update Operations
New in version 4.2.
In mongo
, create a newStudents
collection with the following documents:
db.newStudents.insertMany( [ { "_id" : 1, "student" : "Richard", "grade" : "F", "points" : 0, "comments1" : null, "comments2" : null }, { "_id" : 2, "student" : "Jane", "grade" : "A", "points" : 60, "comments1" : "well behaved", "comments2" : "fantastic student" }, { "_id" : 3, "student" : "Ronan", "grade" : "F", "points" : 0, "comments1" : null, "comments2" : null }, { "_id" : 4, "student" : "Noah", "grade" : "D", "points" : 20, "comments1" : "needs improvement", "comments2" : null }, { "_id" : 5, "student" : "Adam", "grade" : "F", "points" : 0, "comments1" : null, "comments2" : null }, { "_id" : 6, "student" : "Henry", "grade" : "A", "points" : 86, "comments1" : "fantastic student", "comments2" : "well behaved" } ] )
Create the following index on the collection:
db.newStudents.createIndex( { grade: 1 } )
The following update operation explicitly hints to
use the index {grade: 1 }
:
db.newStudents.update( { points: { $lte: 20 }, grade: "F" }, // Query parameter { $set: { comments1: "failed class" } }, // Update document { multi: true, hint: { grade: 1 } } // Options )
Note
If you specify an index that does not exist, the operation errors.
The update command returns the following:
WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })
To see the index used, run explain
on the operation:
db.newStudents.explain().update( { "points": { $lte: 20 }, "grade": "F" }, { $set: { "comments1": "failed class" } }, { multi: true, hint: { grade: 1 } } )
The db.collection.explain().update()
does not modify the documents.
Override Default Write Concern
The following operation on a replica set specifies a write
concern of "w: majority"
with a
wtimeout
of 5000 milliseconds such that the method returns after
the write propagates to a majority of the voting replica set members or
the method times out after 5 seconds.
db.books.update( { stock: { $lte: 10 } }, { $set: { reorder: true } }, { multi: true, writeConcern: { w: "majority", wtimeout: 5000 } } )
Specify Collation
Specifies the collation to use for the operation.
Collation allows users to specify language-specific rules for string comparison, such as rules for lettercase and accent marks.
The collation option has the following syntax:
collation: { locale: <string>, caseLevel: <boolean>, caseFirst: <string>, strength: <int>, numericOrdering: <boolean>, alternate: <string>, maxVariable: <string>, backwards: <boolean> }
When specifying collation, the locale
field is mandatory; all
other collation fields are optional. For descriptions of the fields,
see Collation Document.
If the collation is unspecified but the collection has a
default collation (see db.createCollection()
), the
operation uses the collation specified for the collection.
If no collation is specified for the collection or for the operations, MongoDB uses the simple binary comparison used in prior versions for string comparisons.
You cannot specify multiple collations for an operation. For example, you cannot specify different collations per field, or if performing a find with a sort, you cannot use one collation for the find and another for the sort.
New in version 3.4.
From the mongo
shell, create a collection named
myColl
with the following documents:
db.myColl.insertMany( [ { _id: 1, category: "café", status: "A" }, { _id: 2, category: "cafe", status: "a" }, { _id: 3, category: "cafE", status: "a" } ])
The following operation includes the collation
option and sets multi
to true
to update all matching documents:
db.myColl.update( { category: "cafe" }, { $set: { status: "Updated" } }, { collation: { locale: "fr", strength: 1 }, multi: true } )
The write result of the operation returns the following document, indicating that all three documents in the collection were updated:
WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 })
After the operation, the collection contains the following documents:
{ "_id" : 1, "category" : "café", "status" : "Updated" } { "_id" : 2, "category" : "cafe", "status" : "Updated" } { "_id" : 3, "category" : "cafE", "status" : "Updated" }
WriteResult
Successful Results
The db.collection.update()
method returns a
WriteResult()
object that contains the status of the operation.
Upon success, the WriteResult()
object contains the number of
documents that matched the query condition, the number of documents
inserted by the update, and the number of documents modified:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Write Concern Errors
If the db.collection.update()
method encounters write
concern errors, the results include the
WriteResult.writeConcernError
field:
Changed in version 4.4.
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1, "writeConcernError": { "code" : 64, "errmsg" : "waiting for replication timed out", "errInfo" : { "wtimeout" : true, "writeConcern" : { "w" : "majority", "wtimeout" : 100, "provenance" : "getLastErrorDefaults" } } })
The following table explains the possible values of
WriteResult.writeConcernError.provenance
:
Provenance | Description |
---|---|
clientSupplied | The write concern was specified in the application. |
customDefault | The write concern originated from a custom defined
default value. See setDefaultRWConcern . |
getLastErrorDefaults | The write concern originated from the replica set's
settings.getLastErrorDefaults field. |
implicitDefault | The write concern originated from the server in absence
of all other write concern specifications. |
Tip
See also:
Errors Unrelated to Write Concern
If the db.collection.update()
method encounters a non-write
concern error, the results include the WriteResult.writeError
field:
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 7, "errmsg" : "could not contact primary for replica set shard-a" } })