Details
-
New Feature
-
Resolution: Unresolved
-
Major - P3
-
None
-
None
-
Query Execution
Description
bernard.gorman and I had a long discussion about this when working on SERVER-43860. Today, with a shard key pattern of {"bar.x": 1, "bar.y": 1} you are able to do an upsert in either of the following ways:
mongos> db.bar.replaceOne({"bar": {x: 3, "y": 3}}, {unrelated: 2}, {upsert: true}) |
{
|
"acknowledged" : true, |
"matchedCount" : 0, |
"modifiedCount" : 0, |
"upsertedId" : ObjectId("5dcc733e983b13bb23055039") |
}
|
mongos> db.bar.replaceOne({"bar.x": 2, "bar.y": 5}, {unrelated: 4}, {upsert: true}) |
{
|
"acknowledged" : true, |
"matchedCount" : 0, |
"modifiedCount" : 0, |
"upsertedId" : ObjectId("5dcc734f983b13bb23055041") |
}
|
However, because _id is immutable, we are not quite smart enough to allow you to perform both styles of update when your shard key is {"_id.x": 1, "_id.y": 1}. You can only perform the version which specifies the entire _id object:
mongos> db.testing.update({_id: {x: 150, y: 150}}, {_id: {x: 150, y: 150}, updated: true}, true) |
WriteResult({
|
"nMatched" : 0, |
"nUpserted" : 1, |
"nModified" : 0, |
"_id" : { |
"x" : 150, |
"y" : 150 |
}
|
})
|
mongos> db.testing.update({"_id.x": 150, "_id.y": 150}, {_id: {x: 150, y: 150}, updated: true}, true) |
WriteResult({
|
"nMatched" : 0, |
"nUpserted" : 0, |
"nModified" : 0, |
"writeError" : { |
"code" : 111, |
"errmsg" : "field at '_id' must be exactly specified, field at sub-path '_id.x'found" |
}
|
})
|
mongos> db.testing.update({"_id.x": 150, "_id.y": 150}, {updated: true}, true) |
WriteResult({
|
"nMatched" : 0, |
"nUpserted" : 0, |
"nModified" : 0, |
"writeError" : { |
"code" : 61, |
"errmsg" : "Expected replacement document to include all shard key fields, but the following were omitted: { missingShardKeyFields: [ \"_id.x\", \"_id.y\" ] }" |
}
|
})
|
This is of course inconsistent. It also seems prudent to favor the dotted-path form of querying over the explicit object, to avoid issues like {x: 1, y: 1} not comparing equal to {y: 1, x: 1}.