I saw your answer on SO about the difference between “update” and “findAndModify”, could you explain in more detail what the difference is, and why MongoDB findAndModify is named what it is?
What’s in a name? that which we call a rose
By any other name would smell as sweet;
- said Juliet1
As it turns out, a lot is in a name. A poorly chosen name can confuse many users, year after year. I believe
findAndModify was probably not the best name for the role that it plays.
An update finds an appropriate document (by default it’s just one) and then it changes its contents according to your specification.
The findAndModify command finds an appropriate document (it’s always just one) and then it changes its contents according to your specification and then it returns that exact document that it changed (old version or new version, depending on which you ask for)
They both find a document and update it atomically. What that means is that it’s not possible for another thread to change part of this document between the time we find it and start updating it and when we finish updating it. It also means that no other thread will see this document in “half-updated” state. That’s what “atomic” means - all-or-nothing.
What if we need to get the full document that we just updated (like marking an item in a queue “yours” and then working on it)?
What I said on StackOverflow was:
If you fetch an item and then update it, there may be an update by another thread between those two steps. If you update an item first and then fetch it, there may be another update in-between and you will get back a different item than what you updated.
Doing it “atomically” means you are guaranteed that you are getting back the exact same item you are updating - i.e. no other operation can happen in between.
That’s why you’ll hear people talk about
findAndModify in the context of implementing a queue mechanism -
findAndModify can update a single document to indicate that you are now working on it, and return that same document to you in one operation.
There are scenarios where
findAndModify cannot help you. If you need to update a document based on existing values of a document, you can use many update operators which are atomic and allow you to change a field value without knowing what its current value is, like
$max, etc. They allow you to modify a field without having to read the value of that field first. And they work with a regular
update as well as with
But if you need to set field
a1 based on the current value of the field
b2 then you would have to read the document first and then when executing your update, you would have to ensure that the update is conditional on no one else having changed that document in the meantime and/or by having unique constraints to guarantee it.
There is no way to utilize
findAndModify here, because it’s limited to the exact set of operators that
update uses, all it adds is the ability to return the exact document you modified. Of course,
findAndModify has to do more work than
update so for best performance you should only use
findAndModify when you must have the document that you just updated back in the application. If you just want to know if an
update succeeded, you can examine the WriteResult that update returns.
findAndModify to a name that more accurately describes its function. It updates a document and returns it, but to maintain a small connection to its current name, I nearby propose we rename it:
Who’s with me? 2