I have a collection named messages sharded on [ _id, userId ]
findAndModify with upsert : false will fail if the predicate is only the _id.
For example:
db.getCollection("messages").findAndModify({
query: {
_id : ObjectId("507f1f77bcf86cd799439011")
},
update: {
$set : { "s_messageBody" : "Hello" }
},
upsert: false
})
This gives errmsg : “Query for sharded findAndModify must contain the shard key”
Interestingly, the equivalent update query will succeed :
db.getCollection("messages").update(
{
_id : ObjectId("507f1f77bcf86cd799439011")
},
{
$set : { "s_messageBody" : "Hello" }
},
{
upsert: false,
multi: false
})
Looking at the explain for the update, I noticed an “IDHACK” plan.
"winningPlan" : {
"stage" : "UPDATE",
"inputStage" : {
"stage" : "IDHACK"
}
},
Can you explain why the query works for a regular update, but not findAndModify?
I am using Mongo 4.2.3