Почему этот медленный запрос MongoDB неправильно использует индекс? - PullRequest
0 голосов
/ 14 мая 2019

У меня есть коллекция в MongoDB, в которой хранятся данные для списков недвижимости: адрес недвижимости, спальни, ванные комнаты и т. Д. ... Конечные пользователи могут выполнять поиск недвижимости и фильтровать более 50 полей (например, «Я хочу просмотреть объекты стоимостью более 500 долларов США»).K с более чем 3 ванными комнатами »), что затрудняет включение фильтруемых полей в указатель.Чтобы обойти эту проблему, я воспользовался советом https://dzone.com/articles/mongodb-indexing-tip-3-how и храню все фильтруемые поля в дочернем массиве, например:

{
  "PropertyId": 123,
  "StreetAddress1": "49 Yarmouth Ln",
  "City", "North East",
  "Fields": [
     { "k": "Bedrooms", "v": 5 },
     { "k": "Bathrooms", "v": 3 },
     { "k": "ListPrice", "v": 450000 },
     ...
  ]
}

Затем я создал индекс, например, так::

db.PropertyListing.ensureIndex( { "Fields.k": 1, "Fields.v": 1 }, { name: 'PropertyListingIndex' } );

Это работает несколько, однако, когда я пытаюсь запросить несколько вещей в массиве Fields:

 $match: {
                        Fields: {
                            $all: [
                                { $elemMatch: { k: "CityPlaceId", v: 50636770 } },
                                { $elemMatch: { k: "Bedrooms", v: 3 } },
                            ]
                        }
                    }

... запрос выполняется медленнее, чем ожидалось.Когда я использую функцию .explain (), она показывает следующее:

"inputStage": {
                        "stage": "IXSCAN",
                        "keyPattern": {
                            "Fields.k": 1,
                            "Fields.v": 1
                        },
                        "indexName": "PropertyListingIndex",
                        "isMultiKey": true,
                        "multiKeyPaths": {
                            "Fields.k": ["Fields"],
                            "Fields.v": ["Fields"]
                        },
                        "isUnique": false,
                        "isSparse": false,
                        "isPartial": false,
                        "indexVersion": 2,
                        "direction": "forward",
                        "indexBounds": {
                            "Fields.k": ["[\"CityPlaceId\", \"CityPlaceId\"]"],
                            "Fields.v": ["[50636770, 50636770]"]
                        }
                    }

Если я правильно читаю, это говорит о том, что он использует только CityPlaceId для сканирования индекса, он не использует другиеполя (например, "Спальни").Это объясняет, почему это медленно, если он использует индекс только для одного отфильтрованного поля.Так работают индексы, они могут сканировать только одно поле в индексированном массиве?Я должен использовать индексированный массив, потому что у меня так много полей, к которым мне нужно обратиться, поэтому я не совсем понимаю, как можно исправить эту ситуацию.Есть идеи ??

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