Я пытаюсь понять, почему Mongo не может использовать закрытый индекс в моем запросе с использованием $nin
, и как его решить. Моя проблема связана с составным индексом, но это происходит и с простым индексом.
Возьмите простой документ:
{b: "text1"}
И простой индекс:
{
"v" : 1,
"key" : {
"b" : 1
},
"name" : "b_1",
"ns" : "mytest"
}
И я подумал, что это простой count()
запрос:
db.mytest.count( {b: $nin: [ "foo" ]}, {b:1, _id:0} )
winningPlan
неожиданно включает FETCH
:
"winningPlan" : {
"stage" : "COUNT",
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"b" : 1
},
"indexName" : "b_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"b" : [
"[MinKey, \"foo\")",
"(\"foo\", MaxKey]"
]
}
}
}
}
Но с простым условием равенства он использует COUNT_SCAN
(как и ожидалось):
> db.mytest.count( {b: "bar" }, {b:1, _id:0} )
"winningPlan" : {
"stage" : "COUNT",
"inputStage" : {
"stage" : "COUNT_SCAN",
"keyPattern" : {
"b" : 1
},
"indexName" : "b_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1
}
},
Чтобы сделать вещи более интересными, find()
вместо count()
не просматривает никаких документов:
> db.mytest.find({b:{ $nin: [ 3 ] }}, {b:1, _id:0})
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"b" : 1,
"_id" : 0
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"b" : 1
},
"indexName" : "b_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"b" : [
"[MinKey, 3.0)",
"(3.0, MaxKey]"
]
}
}
}
Зачем Монго нужно FETCH
с $nin
? Это должно быть в состоянии выполнить это исключительно из индекса.