Монго-индексы на массивах - PullRequest
0 голосов
/ 23 сентября 2018

У меня есть документ на монго, как показано ниже.Здесь проекты будут похожи на первый проект с индексом массива 0, второй проект с индексом массива 1, третий проект с индексом массива 2, ....

{
  "_id": "234463456453643563456",
  "name": "Mike",
  "empId": "10",
  "managerId": "8",
  "projects" : [ "123", "456", "789"]
}

У меня есть индекс для поля проектов иЯ хотел бы искать сотрудников, чей первый проект 123, второй проект 456, ...

У меня есть следующий индекс,

createIndex({"projects":1});

Когда я ищу, как показано ниже, это занимаетвремя.

{"$ or": [{"projects.2": "123"}, {"projects.4": "456"}, {"projects.3": "789 "}, {" projects.1 ":" 5467 "}, {" projects.0 ":" 9768 "}]}

Но тот же запрос работает очень хорошо после создания таких индексов, как, это действительно быстро.

createIndex({"projects.0":1});
createIndex({"projects.1":1});
createIndex({"projects.2":1});
createIndex({"projects.3":1});
createIndex({"projects.4":1});
createIndex({"projects.5":1});

Это экономит 3 секунды для каждого запроса после создания индекса.

Как это работает внутри?Почему такая большая разница?

1 Ответ

0 голосов
/ 23 сентября 2018

Действительно легко увидеть, как это работает, если вы используете команду объяснение .Вот краткая сводка:

Моя коллекция тестов:

{
    "_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.

Надеюсь, это вам поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...