[SERVER-13843] Upsert fails with error when query document includes multiple equality predicates on same field Created: 06/May/14  Updated: 06/Dec/22

Status: Backlog
Project: Core Server
Component/s: Write Ops
Affects Version/s: 2.6.1, 2.7.0
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: J Rassi Assignee: Backlog - Query Optimization
Resolution: Unresolved Votes: 14
Labels: query-44-grooming
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
Duplicate
is duplicated by SERVER-23632 Take field value from $setOnInsert wh... Closed
Related
related to SERVER-3946 Update with $addToSet/$push with a qu... Closed
Assigned Teams:
Query Optimization
Operating System: ALL
Participants:

 Description   

Regression introduced in 2.5.5 by SERVER-11389.

Upsert operations will fail with error "Cannot create base during insert of update" when the query document includes multiple equality predicates on the same field. Query predicates that use $all are affected; query predicates that use $and with multiple predicates that are explicitly given on the same field are also affected.

See the following example:

> db.version()
2.6.1
> db.foo.drop()
false
> db.foo.update({a:{$all:[0,1]}},{$set:{b:1}},{upsert:true})
WriteResult({
	"nMatched" : 0,
	"nUpserted" : 0,
	"writeError" : {
		"code" : 12,
		"errmsg" : "Cannot create base during insert of update. Caused by :ConflictingUpdateOperators Cannot update 'a' and 'a' at the same time"
	}
})

The following illustrates how to work around the issue in the above example:

> db.foo.update({$and:[{a:{$elemMatch:{$lte:0,$gte:0}}},{a:{$elemMatch:{$lte:1,$gte:1}}}]},{$set:{b:1}},{upsert:true})
WriteResult({
	"nMatched" : 0,
	"nUpserted" : 1,
	"nModified" : 0,
	"_id" : ObjectId("53691eda8f8f0d777fb2be69")
})

Original report from mongodb-user: <https://groups.google.com/forum/#!topic/mongodb-user/UcKvx4p4hnY>



 Comments   
Comment by Asya Kamsky [ 30/Jun/19 ]

There is a workaround for this issue:

db.foo.update({a:{$all:[{$elemMatch:{$eq:0}},{$elemMatch:{$eq:1}}]}},{$set:{b:1}},{upsert:true})

This will match when a is an array with both 0 and 1 in it and it will upsert otherwise.

This may be slightly simpler than the workaround in the description.

Comment by Aleksey Izmailov [ 29/Oct/14 ]

I personally got hit by this bug using a query that searches $all DOCUMENTS! in the array. Using $elemMatch workaround is way too tedious - have to compare every single element/field in the document times number of documents.
Is there any plan to fix it, or should I downgrade to 2.4/2.5?
Thanks

Generated at Thu Feb 08 03:33:04 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.