[SERVER-8172] a query field with a $not operator should not be used to populate an upsert document Created: 15/Jan/13 Updated: 28/Oct/15 Resolved: 18/Jan/13 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Querying, Write Ops |
| Affects Version/s: | 2.2.2 |
| Fix Version/s: | 2.2.4, 2.4.0-rc0 |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | James Hartig | Assignee: | Aaron Staple |
| Resolution: | Done | Votes: | 1 |
| Labels: | elemmatch, update, upsert | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Environment: |
MongoDB v2.2.2 or MongoDB v2.0.6 |
||
| Backwards Compatibility: | Fully Compatible |
| Operating System: | ALL |
| Steps To Reproduce: | db.test.update({_id: 1, r: {$not: {$elemMatch: {"a": 1}}}}, {$push: {r: {"a": 1, "e": 0}}}, {upsert: true}); |
| Participants: |
| Description |
|
In 2.0.8, createNewFromQuery performs the following check to see if a
In 2.2.2, that check became the following:
Now we only consider the object field to represent an operator if }} portion of the }}. $push cannot operate on this value Aaron ------------------------------------ In 2.2.x $elemMatch breaks $push when used inside of $not and with an upsert. This is useful is you want to push only when an existing property doesn't exist inside of an array. An update in 2.0 such as: }}, {upsert: true}); , {"e": 1}]}}}}, {$push: {r: {"a": 1, "e": 0}}}, {upsert: true}); ] } If you called either of those updates again, it would expectantly throw a 11000 error: or {"e": 1}. Now in 2.2 either of those updates fails with error: There was a proposed workaround (using $nin): http://stackoverflow.com/questions/12391334/mongodb-upsert-with-push-and-not |
| Comments |
| Comment by auto [ 21/Mar/13 ] |
|
Author: {u'date': u'2013-01-16T21:47:34Z', u'name': u'aaron', u'email': u'aaron@10gen.com'}Message: Conflicts: src/mongo/dbtests/updatetests.cpp |
| Comment by Aaron Staple [ 16/Jan/13 ] |
|
$not is the only additional operator valid in this context. $and is not a field-value operator and cannot be correctly supplied here in a query. We can revisit the implementation choice after |
| Comment by James Hartig [ 16/Jan/13 ] |
|
Instead of another if checking for just $not, should there be another method like getGtLtOp that checks for $gt/$lt and other operators too? Is $and/$or going to be broken? |
| Comment by auto [ 16/Jan/13 ] |
|
Author: {u'date': u'2013-01-16T21:47:34Z', u'email': u'aaron@10gen.com', u'name': u'aaron'}Message: |
| Comment by James Hartig [ 16/Jan/13 ] |
|
This is slated for 2.4.x. Can we get this fixed in 2.2.x? |