Действительно легко увидеть, как это работает, если вы используете команду объяснение .Вот краткая сводка:
Моя коллекция тестов:
{
"_id" : ObjectId("5b7fa665844b5ebfad064b1c"),
"arr" : [ "123", "456", "789"]
},
{
"_id" : ObjectId("5b80f96e9fceda195ba853af"),
"arr" : [ "ABC", "DEF", "FOO"]
}
Мой индекс: createIndex({"arr":1})
Теперь, если я выполню поиск как find({arr: '123'}).explain()
, мы увидимиз explain result
:
...
"indexName" : "_arr_",
"isMultiKey" : true,
"multiKeyPaths" : {
"arr" : [
"arr"
]
},
...
, что использовался правильный индекс.А что насчет find({arr.0: '123'}).explain()
?
...
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"arr.0" : {
"$eq" : "123"
}
},
"direction" : "forward"
},
...
Что ж, теперь мы получаем прекрасный полный COLLSCAN
в качестве "выигрышного" плана:).
Далее createIndex({"arr.0":1});
, а затем find({arr.0: '123'}).explain()
дает нам:
...
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"arr.0" : 1
},
"indexName" : "_arr.0_",
"isMultiKey" : false,
"multiKeyPaths" : {
"arr.0" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"arr.0" : [
"[\"123\", \"123\"]"
]
}
}
}
...
Так что, как вы видите, индекса multiKey на arr
недостаточно, если вы собираетесь искать по индексу массива, так как:
MongoDB создаетиндексный ключ для каждого элемента в массиве.Эти многопользовательские индексы поддерживают эффективные запросы к полям массива
Так что именно так и происходит, когда вы выполняете начальный индекс ... mongo находит документ, который содержит 123
, но в вашем случае вы хотитеполучите конкретный запрос индекса массива, для которого вам нужен один индекс, как показано explain
.
Надеюсь, это вам поможет.