[SERVER-14309] can't do non-multi update or upsert with single-value $in query predicate on shard key Created: 19/Jun/14  Updated: 25/Sep/15  Resolved: 15/Jun/15

Status: Closed
Project: Core Server
Component/s: Querying, Sharding
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Minor - P4
Reporter: Asya Kamsky Assignee: Unassigned
Resolution: Duplicate Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: File hashed_shard_key_in.js    
Issue Links:
Depends
Duplicate
duplicates SERVER-12024 re-implement $in in terms of $or Backlog
is duplicated by SERVER-17458 Update with upsert true with _id 'in'... Closed
Related
related to SERVER-12024 re-implement $in in terms of $or Backlog
Participants:

 Description   

Symptom:

db.timeline_cache.update({_id: { $in: ["100"]} }, { $push: { _c: { $each: [ { _id: ObjectId('53a20638e4b0df77093c1abb'), _a: "asya", _m: "OMG, this SUCKS!!!" } ], $slice: -15 } } })
update { q: { _id: { $in: [ "100" ] } }, u: { $push: { _c: { $each: [ { _id: ObjectId('53a20638e4b0df77093c1abb'), _a: "asya", _m: "OMG!!!" } ], $slice: -15.0 } } }, multi: false, upsert: false } does not contain _id or shard key for pattern { _id: "hashed" }
WriteResult({
	"nMatched" : 0,
	"nUpserted" : 0,
	"nModified" : 0,
	"writeError" : {
		"code" : 61,
		"errmsg" : "update { q: { _id: { $in: [ \"100\" ] } }, u: { $push: { _c: { $each: [ { _id: ObjectId('53a20638e4b0df77093c1abb'), _a: \"asya\", _m: \"OMG, this SUCKS!!!\" } ], $slice: -15.0 } } }, multi: false, upsert: false } does not contain _id or shard key for pattern { _id: \"hashed\" }"
	}
})

The same update with _id:"100" works fine. Arguably $in:100 could be interpreted during upsert as equality.



 Comments   
Comment by J Rassi [ 15/Jun/15 ]

Sounds good to me. Closing as a dup of SERVER-12024, and updating issue summary to reflect $in discussion.

Comment by Asya Kamsky [ 11/Jun/15 ]

Should we close this as dup of SERVER-12024 since it comes down to the exact same thing ($in with one element not being recognized as equality for purpose of upsert?)

Comment by J Rassi [ 06/Mar/15 ]

As of version 3.0, this issue has been partially addressed. It's still the case that mongos will refuse to perform a non-multi update on a sharded collection if the query portion does not include an equality predicate on the shard key. However, the logic that detects for the presence of the shard key in the query portion has improved. SERVER-14973 added support for parsing the query predicate using the CanonicalQuery path, which applies some simple transformations to the query predicate (e.g. promoting expressions to the root of the tree if they are single child of an OR root or an AND root) before attempting to extract the value of the shard key.

See the shell snippet below, which shows a successful non-multi update on a sharded collection where the equality predicate on the shard key is wrapped inside a trivial OR:

mongos> sh.enableSharding("test")
{ "ok" : 1 }
mongos> sh.shardCollection("test.foo",{_id:"hashed"})
{ "collectionsharded" : "test.foo", "ok" : 1 }
mongos> db.foo.update({$or: [{_id: 5}]}, {$set: {a:1} }, {upsert:true} )
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 5 })
mongos> db.foo.find()
{ "_id" : 5, "a" : 1 }

But note that $in with a single-element array still does not pass. This will work once SERVER-12024 is resolved.

mongos> db.foo.update({_id: {$in: [6]}}, {$set: {a:1} }, {upsert:true} )
WriteResult({
	"nMatched" : 0,
	"nUpserted" : 0,
	"nModified" : 0,
	"writeError" : {
		"code" : 61,
		"errmsg" : "upsert { q: { _id: { $in: [ 6.0 ] } }, u: { $set: { a: 1.0 } }, multi: false, upsert: true } does not contain shard key for pattern { _id: \"hashed\" }"
	}
})

Comment by Daniel Pasette (Inactive) [ 19/Jun/14 ]

The mongos cannot target this query predicate in non multi-update and cannot do an upsert at all with a non-equality predicate.

Comment by Asya Kamsky [ 19/Jun/14 ]

It looks like this didn't work in 2.6.1 or 2.4 so it is not a regression.

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