For my needs, I have to do pre-splitting but my shard key is a compound key. both keys of my compound key (k1 and k2) are int and my desired chunk structure is something like this
chunk1 : k1 = minkey to 1, k2 = minkey to maxkey
chunk2 : k1 = 1 to 2, k2 = minkey to maxkey
chunk3 : k1 = 2 to 3, k2 = minkey to maxkey
chunk4 : k1 = 3 to 4, k2 = minkey to maxkey
…
So what I really want to do is split on the first key only and leave the second key to include all possible ranges but if run this
db.runCommand( { split : "db.mycollection" , middle : { k1: 1} } );
it will fail saying the full shard key is not provided so it makes me to call this
db.runCommand( { split : "db.mycollection" , middle : { k1: 1, k2:somenumber } } );
this command works but the resulted split is bad because it gives me chunks like below
chunk1 : k1 = minkey to 1, k2 = minkey to somenumber
chunk2 : k1 = 1 to maxkey , k2 = somenumber to maxkey
this is bad because if users insert something a document where k1<1 and k2>somenumber, there is no chunk in the system that covers it and the insert should fail.
How can I create such chunk boundaries with my compound key?
NOTE: One may ask why I have k2 if it is always minkey to maxkey. I have k2 like that to allow further splitting on k2 for same k1 in future if needed be ( and I am sure it will be needed on some of chunks)
This should do it :
By the way, you can never create a situation where a certain range is not covered by chunks since all you’re doing is splitting existing ranges. Also note that k2 cannot be from MinKey to MaxKey technically. Your range for the first chunk is going to be
{k1: MinKey, k2: MinKey}to{k1:1, k2: MaxKey}. The next one is going to be{k1: 1, k2: MaxKey}to{k1:2, k2: MaxKey}and so on