Every language has its own syntax, so it shouldn’t be a surprise that MongoDB Query Language has its own rules and syntax. For any language, documentation is important in understanding the arguments, returns, optional values, special remarks associated with any method/command.
Mongosh (MongoDB Shell) documentation:
Documentation for updateOne: https://www.mongodb.com/docs/manual/reference/method/db.collection.updateOne/
Documentation for findAndModify: https://www.mongodb.com/docs/manual/reference/method/db.collection.findAndModify/
If you look at the documentation for updateOne
, its definition is:
db.collection.updateOne(filter, update, options)
where filter and options are specified to be documents, whereas update can be document or pipeline. options
is an optional document. The developers could have embedded these as fields of a document, but in my opinion, they wanted to keep it simple. The first document will be the filter and the second document the update (it is a logical order), so assigning them to fields may make the call to updateOne
more verbose or intricate than necessary.
Contrast this with the definition of findAndModify
:
db.collection.findAndModify(document)
At the top level, the parameters are placed as fields in a document.
In updateOne
, the parameter documents aren’t embedded in a document i.e. in updateOne
the call is:
updateOne( {filter doc}, {update doc}, {options doc} ) // Correct
updateOne({ {filter doc}, {update doc}, {options doc} }) // Not Correct
In findAndModify
within the top-level document, the query, update and other parameters are specified as fields like so:
db.collection.findAndModify({ query: {...}, update: {...}, upsert: <boolean>,
sort: {...}, remove: <boolean>, ... })
Notice in this method, the optional fields aren’t consolidated into one options document. Rather they are separate fields. It makes the method more versatile. For example, we can set the field remove: true
and omit the update
field altogether (this will remove the document matching the query from the collection). We can also specify sort: {...}
to select which matching document gets picked. There is a lot more functionality in the findAndModify
method. If the developers chose the same approach for this method as updateOne
by not using fields, then we would be constrained to order the arguments in a very specific and limited order. Using the field model allows us to to change the order of the fields while passing arguments.
The above is just my opinion. I am not privy to the thinking and considerations of the developers. The simple answer is: This is how the developers chose to implement the methods in mongosh.
As pointed out by barbaka, the course author(s) made a mistake.
// Suppose we have a document in employees collection,
{
"_id" : ObjectId("637cf3dc4a12ed7cca2888b6"),
"empId" : 1,
"name" : "Clark",
"dept" : "Sales",
"age" : 44
}
db.employees.findAndModify({query: {name: 'Clark'}, update: {$set: {age:88}}, new: true});
# With $set. The age field is updated. The rest remains same.
{
"_id" : ObjectId("637cf3dc4a12ed7cca2888b6"),
"empId" : 1,
"name" : "Clark",
"dept" : "Sales",
"age" : 88
}
db.employees.findAndModify({query: {name: 'Clark'}, update: {age:88}, new: true});
# Without $set. Only the _id is the same. Rest of the document fields are gone.
{
"_id" : ObjectId("637cf3dc4a12ed7cca2888b6"),
"age" : 88
}