[SERVER-30225] Sharded writes should extract shard key when it is in every branch of an $or Created: 19/Jul/17  Updated: 06/Dec/22

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

Type: Improvement Priority: Major - P3
Reporter: Tess Avitabile (Inactive) Assignee: Backlog - Query Optimization
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
is duplicated by SERVER-7985 $or within findAndModify with a mongo... Closed
Related
Assigned Teams:
Query Optimization
Participants:
Case:

 Description   

Single updates, upserts, and single deletes are required to target a single shard or have an exact match on the _id. For (non-replacement-style) updates and deletes, the ChunkManagerTargeter checks that the query contains an exact match on the _id using the collection-default collation, or an exact match on the shard key using the simple collation. This is done using extractShardKeyFromQuery. However, we fail to extract the shard key / _id when there is an exact match in every branch of an $or. Then we are unable to perform the write. We should be able to extract the shard key / _id when there is an exact match in every branch of an $or.



 Comments   
Comment by Asya Kamsky [ 18/May/18 ]

ChunkManagerTargeter checks that the query contains an exact match on the _id using the collection-default collation, or an exact match on the shard key using the simple collation.

 

What if the _id is the shard key?  It has to be simple collation then?

 

Comment by David Storch [ 19/Apr/18 ]

This limitation also appears to affect $in:

mongos> db.c.update({a: {$in: [1, 5]}}, {$inc: {foo: 1}})
WriteResult({
	"nMatched" : 0,
	"nUpserted" : 0,
	"nModified" : 0,
	"writeError" : {
		"code" : 61,
		"errmsg" : "A single update on a sharded collection must contain an exact match on _id (and have the collection default collation) or contain the shard key (and have the simple collation). Update request: { q: { a: { $in: [ 1.0, 5.0 ] } }, u: { $inc: { foo: 1.0 } }, multi: false, upsert: false }, shard key pattern: { a: 1.0 }"
	}
})

Furthermore, the findAndModify command is affected in addition to update, for both the $or and $in cases:

mongos> db.c.findAndModify({query: {a: {$or: [{a: 1}, {a: 5}]}}, update: {$inc: {foo: 1}}})
2018-04-19T18:08:50.574-0400 E QUERY    [js] Error: findAndModifyFailed failed: {
	"ok" : 0,
	"errmsg" : "unknown operator: $or",
	"code" : 2,
	"codeName" : "BadValue",
	"$clusterTime" : {
		"clusterTime" : Timestamp(1524175727, 3),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	},
	"operationTime" : Timestamp(1524175727, 3)
} :
mongos> db.c.findAndModify({query: {a: {$in: [1, 5]}}, update: {$inc: {foo: 1}}})
2018-04-19T18:07:11.325-0400 E QUERY    [js] Error: findAndModifyFailed failed: {
	"ok" : 0,
	"errmsg" : "Query for sharded findAndModify must contain the shard key",
	"code" : 61,
	"codeName" : "ShardKeyNotFound",
	"$clusterTime" : {
		"clusterTime" : Timestamp(1524175627, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	},
	"operationTime" : Timestamp(1524175627, 1)
} :

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