You cannot have a scan and order value of 0 when you try to use sorting on the composite key side. Unfortunately, there is currently no solution for your problem that is not related to the fact that you are using the 2d index or otherwise.
When you execute the explanation command at your request, the value of "scanAndOrder" indicates the weather, it was necessary to have a sort phase after collecting the result or not. If this is true, sorting after the request was necessary, if this false sorting is not needed.
To check the situation, I created a collection named t2 in the db sample as follows:
db.createCollection('t2') db.t2.ensureIndex({a:1}) db.t2.ensureIndex({b:1}) db.t2.ensureIndex({a:1,b:1}) db.t2.ensureIndex({b:1,a:1}) for(var i=0;i++<200;){db.t2.insert({a:i,b:i+2})}
While you can use only 1 index to support the query, I performed the following test with the results included:
mongos> db.t2.find({a:{$gt:50}}).sort({b:1}).hint("b_1").explain() { "cursor" : "BtreeCursor b_1", "isMultiKey" : false, "n" : 150, "nscannedObjects" : 200, "nscanned" : 200, "nscannedObjectsAllPlans" : 200, "nscannedAllPlans" : 200, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, "indexBounds" : { "b" : [ [ { "$minElement" : 1 }, { "$maxElement" : 1 } ] ] }, "server" : "localhost:27418", "millis" : 0 } mongos> db.t2.find({a:{$gt:50}}).sort({b:1}).hint("a_1_b_1").explain() { "cursor" : "BtreeCursor a_1_b_1", "isMultiKey" : false, "n" : 150, "nscannedObjects" : 150, "nscanned" : 150, "nscannedObjectsAllPlans" : 150, "nscannedAllPlans" : 150, "scanAndOrder" : true, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 1, "indexBounds" : { "a" : [ [ 50, 1.7976931348623157e+308 ] ], "b" : [ [ { "$minElement" : 1 }, { "$maxElement" : 1 } ] ] }, "server" : "localhost:27418", "millis" : 1 } mongos> db.t2.find({a:{$gt:50}}).sort({b:1}).hint("a_1").explain() { "cursor" : "BtreeCursor a_1", "isMultiKey" : false, "n" : 150, "nscannedObjects" : 150, "nscanned" : 150, "nscannedObjectsAllPlans" : 150, "nscannedAllPlans" : 150, "scanAndOrder" : true, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 1, "indexBounds" : { "a" : [ [ 50, 1.7976931348623157e+308 ] ] }, "server" : "localhost:27418", "millis" : 1 } mongos> db.t2.find({a:{$gt:50}}).sort({b:1}).hint("b_1_a_1").explain() { "cursor" : "BtreeCursor b_1_a_1", "isMultiKey" : false, "n" : 150, "nscannedObjects" : 150, "nscanned" : 198, "nscannedObjectsAllPlans" : 150, "nscannedAllPlans" : 198, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, "indexBounds" : { "b" : [ [ { "$minElement" : 1 }, { "$maxElement" : 1 } ] ], "a" : [ [ 50, 1.7976931348623157e+308 ] ] }, "server" : "localhost:27418", "millis" : 0 }
Indexes in individual fields do not help much, therefore a_1 (not sorting support) and b_1 (not supported by queryin) are missing. The index on a_1_b_1 will also not be lucky, as long as it works worse than one a_1, the mongoDB engine will not use the situation when the part associated with the value “a” saved in this way. What is worth a try is the composite index b_1_a_1, which in your case is relevant_1_loc_1, while it will return the results in an ordered manner, so scanAndOrder will be false, and I have not tested it for index 2d, but I assume that it excludes scanning Some documents are based only on the index value (therefore, in the test in this case nscanned is higher than nscannedObjects). The index, unfortunately, will be huge, but still smaller than the documents.