ISSUE SUMMARY
When using a 2.6 shell against a 2.4 server, or during the upgrade period where a 2.6 mongos talks to a 2.4 mongod server, the shell returns an incorrect WriteResult for upsert operations where the query predicate includes an equality match on _id with a non-ObjectID type. For example:
db.foo.update({_id:0},{$set:{a:1}},{upsert:true})
"When using a 2.6 shell against a 2.4 server, or during the upgrade period where a 2.6 mongos talks to a 2.4 mongod server..."
Note that non-ObjectID upsert _ids were not reported in v2.4, the issue is the incorrect upsert statistics.
Resolution Details:
The WriteResult returned is:
WriteResult({ "nMatched" : 1, "nUpserted" : 0 })
The correct WriteResult should be one of the following:
WriteResult({ "nMatched" : 0, "nUpserted" : 1 }) WriteResult({ "nMatched" : 0, "nUpserted" : 1, "_id" : <value> })
USER IMPACT
The upsert statistics in WriteResult messages returned by the shell are incorrect.
WORKAROUNDS
getLastError should report the correct upsert statistics.
AFFECTED VERSIONS
MongoDB 2.6.0 and 2.6.1 are affected by this issue.
FIX VERSION
The fix is included in the 2.6.2 production release.
RESOLUTION DETAILS
Do not rely on the presence of the upserted field in the getLastError response to populate write results.
Original description
In compatibility mode, the shell returns an incorrect WriteResult for upserts where the query predicate includes an equality match on _id with a non-OID type.
The WriteResult returned is:
WriteResult({ "nMatched" : 1, "nUpserted" : 0 })
The correct WriteResult should be one of the following:
WriteResult({ "nMatched" : 0, "nUpserted" : 1 }) WriteResult({ "nMatched" : 0, "nUpserted" : 1, "_id" : <value> })
Reproduce with:
MongoDB shell version: 2.6.1 connecting to: test > db.version() 2.4.10 > db.foo.remove({}) Cannot use commands write mode, degrading to compatability mode WriteResult({ "nRemoved" : 0 }) > db.foo.update({_id:ObjectId("ffffffffffffffffffffffff")},{$set:{a:1}},{upsert:true}) // OID type, correct result WriteResult({ "nMatched" : 0, "nUpserted" : 1, "_id" : ObjectId("ffffffffffffffffffffffff") }) > db.foo.update({_id:0},{$set:{a:1}},{upsert:true}) // non-OID type, incorrect result WriteResult({ "nMatched" : 1, "nUpserted" : 0 })
- is related to
-
DRIVERS-151 Handle Bulk API edge case for pre-2.6 servers when upserted _id not returned
- Closed
- related to
-
SERVER-1351 GLE upserted _id field should always be filled in
- Closed