- Reference >
- Database Commands >
- Query and Write Operation Commands >
- findAndModify
findAndModify¶
-
findAndModify¶ The
findAndModifycommand 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 thenewoption.The command has the following syntax:
The
findAndModifycommand 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
queryfield employs the same query selectors as used in thefind()method. Although the query may match multiple documents,findAndModifywill only select one document to modify. - sort (document) – Optional. Determines which document the operation will modify if
the query selects multiple documents.
findAndModifywill modify the first document in the sort order specified by this argument. - remove (boolean) – Must specify either the
removeor theupdatefield in thefindAndModifycommand. Whentrue, removes the selected document. The default isfalse. - update (document) – Must specify either the
removeor theupdatefield in thefindAndModifycommand. Theupdatefield employs the same update operators orfield: valuespecifications to modify the selected document. - new (boolean) – Optional. When
true, returns the modified document rather than the original. ThefindAndModifymethod ignores thenewoption forremoveoperations. The default isfalse. - fields (document) –
Optional. A subset of fields to return. The
fieldsdocument specifies an inclusion of a field with1, as in the following:See projection.
- upsert (boolean) – Optional. Used in conjunction with the
updatefield. Whentrue, thefindAndModifycommand creates a new document if thequeryreturns no documents. The default isfalse.
The
findAndModifycommand returns a document, similar to the following:The return document contains the following fields:
- The
lastErrorObjectfield that returns the details of the command:- The
updatedExistingfield only appears if the command is either anupdateor anupsert. - The
upsertedfield only appears if the command is anupsert.
- The
- The
valuefield that returns either:- the original (i.e. pre-modification) document if
newis false, or - the modified or inserted document if
new: true.
- the original (i.e. pre-modification) document if
- The
okfield that returns the status of the command.
Note
If the
findAndModifyfinds no matching document, then:for
updateorremoveoperations,lastErrorObjectdoes not appear in the return document and thevaluefield holds anull.for an
upsertoperation that performs an insert, whennewisfalse, and includes asortoption, the return document haslastErrorObject,value, andokfields, but thevaluefield holds an empty document{}.for an
upsertthat performs an insert, whennewisfalsewithout a specifiedsortthe return document haslastErrorObject,value, andokfields, but thevaluefield holds anull.Changed in version 2.2: Previously, the command returned an empty document (e.g.
{}) in thevaluefield. See the 2.2 release notes for more information.
Consider the following examples:
The following command updates an existing document in the
peoplecollection where the document matches thequerycriteria:This command performs the following actions:
The
queryfinds a document in thepeoplecollection where thenamefield has the valueTom, thestatefield has the valueactiveand theratingfield has a valuegreater than10.The
sortorders the results of the query in ascending order. If multiple documents meet thequerycondition, the command will select for modification the first document as ordered by thissort.The
updateincrementsthe value of thescorefield by 1.The command returns a document with the following fields:
- The
lastErrorObjectfield that contains the details of the command, including the fieldupdatedExistingwhich istrue, and - The
valuefield that contains the original (i.e. pre-modification) document selected for this update:
To return the modified document in the
valuefield, add thenew:trueoption to the command.If no document match the
querycondition, the command returns a document that containsnullin thevaluefield:- The
The
mongoshell 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 whennewistrue.The following
findAndModifycommand includes theupsert: trueoption to insert a new document if no document matches thequerycondition:If the command does not find a matching document, the command performs an upsert and returns a document with the following fields:
- The
lastErrorObjectfield that contains the details of the command, including the fieldupsertedthat contains theObjectIdof the newly inserted document, and - The
valuefield that contains an empty document{}as the original document because the command included thesortoption:
If the command did not include the
sortoption, thevaluefield would containnull:- The
The following
findAndModifycommand includes bothupsert: trueoption and thenew:trueoption to return the newly inserted document in thevaluefield if a document matching thequeryis not found:The command returns the newly inserted document in the
valuefield:
When the
findAndModifycommand includes theupsert: trueoption 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 thefindAndModifycommand and these commands complete thefindphase before any one starts themodifyphase, these commands could insert the same document.Consider an example where no document with the name
Andyexists and multiple clients issue the following command:If all the commands finish the
queryphase before any command starts themodifyphase, and there is no unique index on thenamefield, the commands may all perform an upsert. To prevent this condition, create a unique index on thenamefield. With the unique index in place, then the multiplefindAndModifycommands would observe one of the following behaviors:- Exactly one
findAndModifywould successfully insert a new document. - Zero or more
findAndModifycommands would update the newly inserted document. - Zero or more
findAndModifycommands 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
findAndModifyin a sharded environment, thequerymust contain the shard key for all operations against the shard cluster.findAndModifyoperations issued againstmongosinstances 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.