I need to execute following query on mongo db:
db.testCollection.find({ dataType: { $exists: true } }, { _id: 0, date: 1 })
.sort({ date: -1 })
.limit(1)
so basically only I need to do is to find newest date from documents that have dataType
field.
I have ~20 milion documents in that collection and this query last something like 4-5 minutes.
I tried to cover all query needs by index, so I created index like this:
db.testCollection.ensureIndex(
{ dataType: 1, date: -1 },
{ partialFilterExpression: { dataType: { $exists: true } } }
)
As far as I know, this index contains all data the query needs:
- information that all documents in this index contains
dataType
field exists date
field value needed to retreived it from querydate
field value needed to sort operation
Unfortunately, mongo still have FETCH
stage in query plan to check if dataType
filed exists:
"winningPlan" : {
"stage" : "PROJECTION_SIMPLE",
"transformBy" : {
"_id" : 0,
"date" : 1
},
"inputStage" : {
"stage" : "SORT",
"sortPattern" : {
"date" : -1
},
"limitAmount" : 1,
"inputStage" : {
"stage" : "SORT_KEY_GENERATOR",
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"dataType" : {
"$exists" : true
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"dataType" : 1,
"date" : -1
},
"indexName" : "dataType_1_date_-1",
"isMultiKey" : false,
"multiKeyPaths" : {
"dataType" : [ ],
"date" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : true,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"dataType" : [
"[MinKey, MaxKey]"
],
"date" : [
"[MaxKey, MinKey]"
]
}
}
}
}
}
}
So my question is why mongo still needs to fetch document from collections?
EDIT: When I changed $exists
operator to $ne: null
it doesn't need to execute FETCH
stage.