Соответственно, MongoDB должен пропустить этап FETCH, когда индекс обращается к запросу.
Если я правильно понял, в этих предложениях объясняется, что:
Покрытые запросы Когда индекс охватываетВ запросе MongoDB может как соответствовать условиям запроса, так и возвращать результаты, используя только ключи индекса;т. е. MongoDB не нужно проверять документы из коллекции для возврата результатов.
Когда индекс покрывает запрос, результат объяснения имеет этап IXSCAN, который не является потомком этапа FETCH, и в executeStats, totalDocsExamined равен 0.
В более ранних версиях MongoDB cursor.explain () возвращал поле indexOnly, чтобы указать, покрывал ли индекс запрос. (https://docs.mongodb.com/manual/reference/explain-results/)
И это
С учетом этого запрос занимает менее 2 мс. Поскольку индекс «покрыл» запрос, MongoDB смогсопоставьте условия запроса и верните результаты, используя только ключи индекса; даже не нужно проверять документы из коллекции, чтобы вернуть результаты. (Если вы видите этап IXSCAN, который не является дочерним по отношению к этапу FETCH, в плане выполнения тогдаиндекс «покрыл» запрос.) (https://studio3t.com/knowledge-base/articles/mongodb-index-strategy/)
Но в тестовом сценарии это не происходит:
Пример для тестирования:
db.Test.insert({"Field1":"data on field1: 1","Field2":"data on field2: 1"});
db.Test.insert({"Field1":"data on field1: 2","Field2":"data on field2: 2"});
db.Test.insert({"Field1":"data on field1: 3","Field2":"data on field2: 3"});
db.Test.insert({"Field1":"data on field1: 4","Field2":"data on field2: 4"});
db.Test.insert({"Field1":"data on field1: 5","Field2":"data on field2: 5"});
db.Test.insert({"Field1":"data on field1: 6","Field2":"data on field2: 6"});
После того как я создал индекс для Field2.
db.Test.createIndex({"Field2":1})
И затем я запрашиваю коллекцию:
db.Test.find({"Field2":"data on field2: 5"}).explain("executionStats");
Я ожидал этап IDXSCAN, который не является дочерним по отношению к этапу FETCH. Но вывод выглядит так:
[...]
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"Campo2" : 1.0
},
"indexName" : "Field2_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"Campo2" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"Field2" : [
"[\"data on field2: 5", \"data on field2: 5\"]"
]
}
}
},
[...]
Существует два этапа: один «этап»: «FETCH», и его дочерний элемент «этап»: «IXSCAN»,.
Может кто-нибудь объяснить, в чем заключается недоразумение?
*** О ПРОЕКТЕ
При выполнении запроса с проекцией
"winningPlan" : {
"stage" : "PROJECTION",
"transformBy" : {
"Campo2" : 1.0
},
"inputStage" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"Field2" : 1.0
},
"indexName" : "Field2_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"Campo2" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"Field2" : [
"[\"data on field2: 5", \"data on field2: 5\"]"
]
}
}
}
},
С ответом Адама: он работал!
Я понял, что проекция не должна включать "_id", чтобы избежать FETCH.