[SERVER-22102] New update operator for compare-and-set pattern Created: 08/Jan/16 Updated: 06/Dec/22 Resolved: 29/Jun/19 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Querying, Write Ops |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | New Feature | Priority: | Major - P3 |
| Reporter: | JianXiong Zhou [X] | Assignee: | Backlog - Query Team (Inactive) |
| Resolution: | Won't Do | Votes: | 4 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||||||
| Assigned Teams: |
Query
|
||||||||||||
| Participants: | |||||||||||||
| Description |
|
Would mongodb provide a new update operator to make compare-and-set updates? Something like:
mongodb set `newValue` to the "foo" field only when the original value of "foo" is equal to `oldValue`. Further more, the `oldValue` could be a boolean expression with the original value, and mongodb updates if the condition is true:
There are already two similar operators: $min and $max, so I think this enhancement should be possible as well. |
| Comments |
| Comment by Asya Kamsky [ 29/Jun/19 ] | |||||
|
You can see some examples here. This can be done now by using various aggregation expressions. | |||||
| Comment by Ramon Fernandez Marina [ 27/Jan/16 ] | |||||
|
We're sending this request to the Query Team for evaluation. | |||||
| Comment by Mark Bigler [ 19/Jan/16 ] | |||||
|
+1 This would also allow to set, but not overwrite values if existing. See
| |||||
| Comment by JianXiong Zhou [X] [ 12/Jan/16 ] | |||||
|
A small declaration: It may be confusing, but my use case is not dealing with multi-documents. My previous comments just for answering Ramón's questions. I have a collection named "User" for storing users' profile, and each profile needs to be reviewed by the administrator. There is a "status" field and its value could be one of "PENDING", "APPROVED" and "REJECTED". The "PENDING" status means it is pending for reviewing, the administrator can change the status from "PENDING" to "APPROVED" or "REJECTED" after reviewing. When in the "APPROVED" status, if the user updates his/her profile, the "status" will become to "PENDING" to inform the administrator to review the profile again. However, the "REJECTED" status can only be changed by the administrator. So I have to update the "status" field conditionally when updating user profiles.
I had implemented this need by: get the value of "status" by findAndModify and then update it if needed. In my opinion, no matter in what use case, using two update commands is not ideal. The extra update command leads to more overload and concurrency issues. Also, the proposed new operator is an enhanced version of $min/$max:
Can I ask why $min and $max were added? | |||||
| Comment by Kelsey Schubert [ 11/Jan/16 ] | |||||
|
Hi X, Can you elaborate on your use case? For example, if you want to set the "bar" field into all documents, and conditionally update the "foo" field. Why not use the following two commands?
Thank you, | |||||
| Comment by JianXiong Zhou [X] [ 09/Jan/16 ] | |||||
|
It is the latter, but the update and $set trick doesn't help. Sometimes we can't specify the condition to the query part, please think about this example:
I believe that was the reason for inventing $min and $max. | |||||
| Comment by Ramon Fernandez Marina [ 09/Jan/16 ] | |||||
|
If the idea is for the $cond operator to provide multi-document atomicity then I'd say this is the same functionality as described in If no multi-document atomicity is required, you can do this today with update and $set. Reusing your examples above:
With the {multi:true} argument the update operation affects all documents in the collection that satisfy the query argument. Does this meet your requirements? | |||||
| Comment by JianXiong Zhou [X] [ 09/Jan/16 ] | |||||
|
The sightly difference between findAndModify and the $cond operator (precisely is the update command) is that findAndModify updates one document at a time, while the $cond operator could effect many documents. In my understanding, findAndModify provides the atomicity in the document level, and the $cond operator just cares about a single field. Please consider it, thanks. | |||||
| Comment by Ramon Fernandez Marina [ 08/Jan/16 ] | |||||
|
zhoujianxiong2@gmail.com, if I understand correctly you're describing functionality already available via findAndModify() – can you please review the semantics of findAndModify and elaborate on how a new operator would perform differently? Thanks, |