Problem: Using a client generated _id instead of using regular objectId and resharding on it generates a projection error.
Details:
The error seems to be coming from how we create pipeline query(specifically $project) in ReshardingSplitPolicy::createRawPipeline. We hit this code path and append ("_id",0) to the pipeline. It seems like shardKey.hasId() check doesn't work as expected.( I removed this check and resharding worked.)
// Do not project _id if it's not part of the shard key. if (!shardKey.hasId()) { projectValBuilder.append("_id", 0); }
The pipeline that is created :
[{"$sample":{"size":0}},{"$project":{"_id._id1":{"$ifNull":["$_id._id1",null]},"_id._id2":{"$ifNull":["$_id._id2",null]},"_id._id3":{"$ifNull":["$_id._id3",null]},"_id":0}},{"$sort":{"_id._id1":1,"_id._id2":1,"_id._id3":1}}]
Steps to reproduce:
1. Customer created a collection and sharded on :
{"_id.id1":1,"_id.id2":1} db.createCollection("colltest4"); sh.shardCollection("dbtest4.colltest4",{"_id.id1":1,"_id.id2":1})
2. They then inserted a few documents as follows:
mongos> db.colltest4.insert({_id:{_id1:1,_id2:1,_id3:1},a:1,b:1})WriteResult({ "nInserted" : 1 }) mongos> db.colltest4.insert({_id:{_id1:2,_id2:2,_id3:1},a:1,b:1})WriteResult({ "nInserted" : 1 }) mongos> db.colltest4.insert({_id:{_id1:2,_id2:2,_id3:2},a:1,b:1})WriteResult({ "nInserted" : 1 }) mongos> db.colltest4.insert({_id:{_id1:2,_id2:2,_id3:2},a:1,b:1})
3. Issued the following Resharding command and got a failure
mongos> db.adminCommand({reshardCollection: "dbtest4.colltest4",key: {"_id.id1":1,"_id.id2":1,"_id.id3":1}}) {"ok" : 0,"errmsg" : "Invalid $project :: caused by :: Path collision at _id","code" : 31250,"codeName" : "Location31250","$clusterTime" : {"clusterTime" : Timestamp(1657698648, 13),"signature" : {"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),"keyId" : NumberLong(0)}
Note: Attaching a js test to reproduce.reshard_coll.js