[SERVER-18076] Upsert rejected with error if _id assigned to in $setOnInsert and _id equality match specified in query predicate Created: 15/Apr/15 Updated: 06/Dec/22 Resolved: 29/Oct/18 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Write Ops |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Improvement | Priority: | Major - P3 |
| Reporter: | J Rassi | Assignee: | Backlog - Query Team (Inactive) |
| Resolution: | Won't Fix | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||||||
| Assigned Teams: |
Query
|
||||||||||||
| Participants: | |||||||||||||
| Description |
|
Upsert are rejected with an error if the update meets both conditions:
See the following reproduction:
And, note that this does not generate an error for other fields:
|
| Comments |
| Comment by Asya Kamsky [ 07/Jul/21 ] | |||||||||||||||||||||||||||||||
|
adrian.blandin@sovo-tech.com (this isn't the best place to discuss workarounds but FYI a way to get this to work without duplicating info is by doing a range find on compound _id field:
Note however that this approach is not thread-safe in the sense that two threads could create a new object with a single chunk each if this field is arbitrarily assigned at insert. | |||||||||||||||||||||||||||||||
| Comment by Adrian B [ 07/Jul/21 ] | |||||||||||||||||||||||||||||||
|
Here is an use case : Having a collection storing arrays of any size (i.e. greater than 16 MB) for another document ("owner"), where the array can be splitted into chunks. That would look like this :
The code above would indicate an error saying that the field "_id" is immutable.
Without allowing to set the "_id" in an upsert, we can still do the above by duplicating the information :
So, it's not a major issue, but we could expect the first code above to work.
| |||||||||||||||||||||||||||||||
| Comment by Asya Kamsky [ 29/Oct/18 ] | |||||||||||||||||||||||||||||||
|
The behavior of disallowing changing _id when matching a document based on _id is consistent with how we treat immutable fields and was implemented this way deliberately.
| |||||||||||||||||||||||||||||||
| Comment by Asya Kamsky [ 29/Jan/18 ] | |||||||||||||||||||||||||||||||
|
This seems works-as-designed/intended. If you are searching for _id 1 and don't find it, then on upsert it doesn't make sense to set _id to anything but 1, at least I can't come up with a reasonable use case. In the example given, the issue was querying with null _id which seems like a logic error somewhere, unless I'm missing something. If it's the case that the only condition on which to determine that a new record should be inserted is if the object is null for query-check but populated for setOnInsert portion of the update, then it sounds like the issue is in the Java/Morphia layer. | |||||||||||||||||||||||||||||||
| Comment by Rajesh Sharma [ 16/Apr/15 ] | |||||||||||||||||||||||||||||||
|
Let me explain why this was useful to use. In our Java based application Client was sending us a Java Object and we were inserting and updating based on Object id. The sample code was as follow(Java Morphia). Query q = ds.createQuery(CustomBenchmarkVO.class).field("_id").equal(customBenchmarkVO.getId()); So in 2.4 when the getId was null the server was inserting that Object as a new document with valid _id key. That make sense as it was a new document so Object id was null for us. Later in 2.6 this production code started breaking. In 2.6 the same code was creating document where _id as null. I was confused why _id is null. Later any call where getId was null was updating the same _id:null document and new document creation stopped. We lost so much data as same object was changed instead of new object creation behavior of 2.4. | |||||||||||||||||||||||||||||||
| Comment by J Rassi [ 16/Apr/15 ] | |||||||||||||||||||||||||||||||
|
The reporter of | |||||||||||||||||||||||||||||||
| Comment by Scott Hernandez (Inactive) [ 16/Apr/15 ] | |||||||||||||||||||||||||||||||
|
What is the practical use case? What application or system would need this | |||||||||||||||||||||||||||||||
| Comment by J Rassi [ 16/Apr/15 ] | |||||||||||||||||||||||||||||||
Yep.
Indeed. This is submitted as a feature request for supporting _id for this use case. | |||||||||||||||||||||||||||||||
| Comment by Scott Hernandez (Inactive) [ 16/Apr/15 ] | |||||||||||||||||||||||||||||||
|
Are you asking to change the _id field on the newly inserted document, to make it different than the value in the query? We currently do not allow a query + update/insert where immutable field values differ between the two: this is true for the _id field or shard key field(s). |