- Reference >
- Database Commands >
- findAndModify
findAndModify¶
-
findAndModify
¶ The
findAndModify
command atomically modifies and returns a single document. By default, the returned document does not include the modifications made on the update. To return the document with the modifications made on the update, use thenew
option.The command has the following syntax:
The
findAndModify
command takes the following fields:Fields: - findAndModify (string) – Required. The collection against which to run the command.
- query (document) – Optional. Specifies the selection criteria for the
modification. The
query
field employs the same query selectors as used in thedb.collection.find()
method. Although the query may match multiple documents,findAndModify
will only select one document to modify. - sort (document) – Optional. Determines which document the operation will modify if
the query selects multiple documents.
findAndModify
will modify the first document in the sort order specified by this argument. - remove (boolean) – Optional if
update
field exists. Whentrue
, removes the selected document. The default isfalse
. - update (document) – Optional if
remove
field exists. Performs an update of the selected document. Theupdate
field employs the same update operators orfield: value
specifications to modify the selected document. - new (boolean) – Optional. When
true
, returns the modified document rather than the original. ThefindAndModify
method ignores thenew
option forremove
operations. The default isfalse
. - fields (document) –
Optional. A subset of fields to return. The
fields
document specifies an inclusion of a field with1
, as in the following:See projection.
- upsert (boolean) – Optional. Used in conjunction with the
update
field. Whentrue
, thefindAndModify
command creates a new document if thequery
returns no documents. The default isfalse
.
The
findAndModify
command returns a document, similar to the following:The return document contains the following fields:
- The
lastErrorObject
field that returns the details of the command:- The
updatedExisting
field only appears if the command is either anupdate
or anupsert
. - The
upserted
field only appears if the command is anupsert
.
- The
- The
value
field that returns either:- the original (i.e. pre-modification) document if
new
is false, or - the modified or inserted document if
new: true
.
- the original (i.e. pre-modification) document if
- The
ok
field that returns the status of the command.
Note
If the
findAndModify
finds no matching document, then:for
update
orremove
operations,lastErrorObject
does not appear in the return document and thevalue
field holds anull
.for an
upsert
operation that performs an insert, whennew
isfalse
, and includes asort
option, the return document haslastErrorObject
,value
, andok
fields, but thevalue
field holds an empty document{}
.for an
upsert
that performs an insert, whennew
isfalse
without a specifiedsort
the return document haslastErrorObject
,value
, andok
fields, but thevalue
field holds anull
.Changed in version 2.2: Previously, the command returned an empty document (e.g.
{}
) in thevalue
field. See the 2.2 release notes for more information.
Consider the following examples:
The following command updates an existing document in the
people
collection where the document matches thequery
criteria:This command performs the following actions:
The
query
finds a document in thepeople
collection where thename
field has the valueTom
, thestate
field has the valueactive
and therating
field has a valuegreater than
10.The
sort
orders the results of the query in ascending order. If multiple documents meet thequery
condition, the command will select for modification the first document as ordered by thissort
.The
update
increments
the value of thescore
field by 1.The command returns a document with the following fields:
- The
lastErrorObject
field that contains the details of the command, including the fieldupdatedExisting
which istrue
, and - The
value
field that contains the original (i.e. pre-modification) document selected for this update:
To return the modified document in the
value
field, add thenew:true
option to the command.If no document match the
query
condition, the command returns a document that containsnull
in thevalue
field:- The
The
mongo
shell and many drivers provide afindAndModify()
helper method. Using the shell helper, this previous operation can take the following form:However, the
findAndModify()
shell helper method returns just the unmodified document, or the modified document whennew
istrue
.The following
findAndModify
command includes theupsert: true
option to insert a new document if no document matches thequery
condition:If the command does not find a matching document, the command performs an upsert and returns a document with the following fields:
- The
lastErrorObject
field that contains the details of the command, including the fieldupserted
that contains theObjectId
of the newly inserted document, and - The
value
field that contains an empty document{}
as the original document because the command included thesort
option:
If the command did not include the
sort
option, thevalue
field would containnull
:- The
The following
findAndModify
command includes bothupsert: true
option and thenew:true
option to return the newly inserted document in thevalue
field if a document matching thequery
is not found:The command returns the newly inserted document in the
value
field:
When the
findAndModify
command includes theupsert: true
option and the query field(s) is not uniquely indexed, the method could insert a document multiple times in certain circumstances. For instance, if multiple clients issue thefindAndModify
command and these commands complete thefind
phase before any one starts themodify
phase, these commands could insert the same document.Consider an example where no document with the name
Andy
exists and multiple clients issue the following command:If all the commands finish the
query
phase before any command starts themodify
phase, and there is no unique index on thename
field, the commands may all perform an upsert. To prevent this condition, create a unique index on thename
field. With the unique index in place, then the multiplefindAndModify
commands would observe one of the following behaviors:- Exactly one
findAndModify
would successfully insert a new document. - Zero or more
findAndModify
commands would update the newly inserted document. - Zero or more
findAndModify
commands would fail when they attempted to insert a duplicate. If the command fails due to a unique index constraint violation, you can retry the command. Absent a delete of the document, the retry should not fail.
Warning
When using
findAndModify
in a sharded environment, thequery
must contain the shard key for all operations against the shard cluster.findAndModify
operations issued againstmongos
instances for non-sharded collections function normally.Note
This command obtains a write lock on the affected database and will block other operations until it has completed; however, typically the write lock is short lived and equivalent to other similar
update()
operations.