|
Sorry for not replying sooner, but I think I agree with this outcome. I was somewhat mislead by a misreading of the output when adding a {x: {$ne: null}} predicate, since it looks like it does use the index, but not for providing a sort:
> db.blah.createIndex({'$**': 1})
|
{
|
"numIndexesBefore" : 1,
|
"numIndexesAfter" : 2,
|
"createdCollectionAutomatically" : true,
|
"ok" : 1
|
}
|
> db.blah.find({x:{$ne:null}}).sort({x: -1}).explain()
|
{
|
"explainVersion" : "1",
|
"queryPlanner" : {
|
"namespace" : "test.blah",
|
"indexFilterSet" : false,
|
"parsedQuery" : {
|
"x" : {
|
"$not" : {
|
"$eq" : null
|
}
|
}
|
},
|
"queryHash" : "01F26CBA",
|
"planCacheKey" : "560833DE",
|
"maxIndexedOrSolutionsReached" : false,
|
"maxIndexedAndSolutionsReached" : false,
|
"maxScansToExplodeReached" : false,
|
"winningPlan" : {
|
"stage" : "SORT",
|
"sortPattern" : {
|
"x" : -1
|
},
|
"memLimit" : 104857600,
|
"type" : "simple",
|
"inputStage" : {
|
"stage" : "FETCH",
|
"filter" : {
|
"x" : {
|
"$not" : {
|
"$eq" : null
|
}
|
}
|
},
|
"inputStage" : {
|
"stage" : "IXSCAN",
|
"keyPattern" : {
|
"$_path" : 1,
|
"x" : 1
|
},
|
"indexName" : "$**_1",
|
"isMultiKey" : false,
|
"multiKeyPaths" : {
|
"$_path" : [ ],
|
"x" : [ ]
|
},
|
"isUnique" : false,
|
"isSparse" : false,
|
"isPartial" : false,
|
"indexVersion" : 2,
|
"direction" : "forward",
|
"indexBounds" : {
|
"$_path" : [
|
"[\"x\", \"x\"]",
|
"[\"x.\", \"x/\")"
|
],
|
"x" : [
|
"[MinKey, MaxKey]"
|
]
|
}
|
}
|
}
|
},
|
"rejectedPlans" : [ ]
|
},
|
"command" : {
|
"find" : "blah",
|
"filter" : {
|
"x" : {
|
"$ne" : null
|
}
|
},
|
"sort" : {
|
"x" : -1
|
},
|
"$db" : "test"
|
},
|
"serverInfo" : {
|
"host" : "ip-10-122-10-16",
|
"port" : 27017,
|
"version" : "4.9.0-alpha4-13-gbed3256",
|
"gitVersion" : "bed32560b4ef8df1eb6635c6d756119ab0e685a4"
|
},
|
"ok" : 1
|
}
|
And it looks like we already do the right thing if you use {x: {$type: 'number'}} to clamp it to numeric values:
> db.blah.find({x:{$type:'number'}}).sort({x: -1}).explain()
|
{
|
"explainVersion" : "1",
|
"queryPlanner" : {
|
"namespace" : "test.blah",
|
"indexFilterSet" : false,
|
"parsedQuery" : {
|
"x" : {
|
"$type" : [
|
"number"
|
]
|
}
|
},
|
"queryHash" : "3592C2C7",
|
"planCacheKey" : "5167D264",
|
"maxIndexedOrSolutionsReached" : false,
|
"maxIndexedAndSolutionsReached" : false,
|
"maxScansToExplodeReached" : false,
|
"winningPlan" : {
|
"stage" : "FETCH",
|
"inputStage" : {
|
"stage" : "IXSCAN",
|
"keyPattern" : {
|
"$_path" : 1,
|
"x" : 1
|
},
|
"indexName" : "$**_1",
|
"isMultiKey" : false,
|
"multiKeyPaths" : {
|
"$_path" : [ ],
|
"x" : [ ]
|
},
|
"isUnique" : false,
|
"isSparse" : false,
|
"isPartial" : false,
|
"indexVersion" : 2,
|
"direction" : "backward",
|
"indexBounds" : {
|
"$_path" : [
|
"[\"x\", \"x\"]"
|
],
|
"x" : [
|
"[inf.0, nan.0]"
|
]
|
}
|
}
|
},
|
"rejectedPlans" : [ ]
|
},
|
"command" : {
|
"find" : "blah",
|
"filter" : {
|
"x" : {
|
"$type" : "number"
|
}
|
},
|
"sort" : {
|
"x" : -1
|
},
|
"$db" : "test"
|
},
|
"serverInfo" : {
|
"host" : "ip-10-122-10-16",
|
"port" : 27017,
|
"version" : "4.9.0-alpha4-13-gbed3256",
|
"gitVersion" : "bed32560b4ef8df1eb6635c6d756119ab0e685a4"
|
},
|
"ok" : 1
|
}
|
So it currently is possible to get a sort out of a wildcard index, but it requires adding a possibly unnecessary predicate to help out the optimizer, since it doesn't know whether there are no non-numeric values.
|