MongoDB фильтрация по многим параметрам (составной индекс или нет) - PullRequest
2 голосов
/ 22 февраля 2012

У меня есть каталог товаров, и я хочу отфильтровать его по многим параметрам: категория, цена, размер, цвет, вес и т. д.

Так что вопрос об индексации.

Я могу попытаться использовать составной индекс для всех полей и запросить их в том же порядке, в котором я их проиндексировал. Но что, если мне нужно фильтровать только по размеру и цвету, а затем только по цене и весу? Создание составного индекса для каждого возможного запроса на фильтрацию было бы излишним, поскольку может быть слишком много параметров.

Итак, после некоторого поиска я нашел интересный подход

Здесь предлагается использовать "нормализованные атрибуты":

{color: "red"} = 10
{weight: 125} = 25
{size: "M"} = 30

и теперь запись монго будет выглядеть так:

{_id: ..., attributes: [10,25,30]}

Затем я должен индексировать по атрибутам, и после этого я могу сделать запрос следующим образом:

db.items.find(attributes: {$all: [10,25,30]})

Значения:

  • меньшие индексы
  • быстрый поиск
  • любое количество параметров
  • легко растет

Что я не понял, как я могу получить эти числа для каждого атрибута? Они рассчитываются как-то (как md5)? Или я должен создать другую коллекцию и хранить там каждый номер ключа-значения? И сначала получить числа оттуда - каждый раз, когда мне нужно отфильтровать коллекцию "предметов"?

А что вы думаете об этом подходе?

UPDATE: Что если я буду использовать соединенные строки вместо чисел?

{_id: ..., attributes: ["language.English", "color.red"]}

1 Ответ

1 голос
/ 22 февраля 2012

Поиск (эффективно) в каталоге магазина - действительно нетривиальная задача.

Да, вы можете создать дополнительную коллекцию и сохранить там все значения

{name: "language", value: "English", numValue: "13"}

Нет, вам не нужно повторно запрашивать эту коллекцию каждый раз. Размер данных здесь, скорее всего, будет небольшим, поэтому вы можете кэшировать его в процессе приложения. Не забывайте подсказку: всегда ставьте сначала атрибут с наименьшим количеством элементов.

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

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