Вопрос по search, mongodb – Решение для хранилища данных для поиска тегов

5

Я получил миллионы товаров, заказанных по предварительно подсчитанному количеству баллов. Каждый элемент имеет множество логических атрибутов.   Пусть говорит, что существует около десяти тысяч возможных атрибутов, каждый из которых имеет дюжину из них.

Я хотел бы иметь возможность запроситьin realtime (несколько миллисекунд) первые n элементов, заданные ~ любая комбинация атрибутов.

Какое решение вы бы порекомендовали? Я ищу что-то чрезвычайно масштабируемое.

--
- В настоящее время мы смотрим наmongodb и индекс массива, вы видите какие-либо ограничения?
- SolR  это возможное решение, но нам не нужны возможности текстового поиска.

когда вы говорите «заказано по счету» Вы имеете в виду, что это уже предварительно вычислено? Если это так, то SOLR может не дать никакой выгоды. Если нет, тогда SOLR предоставляет очень мощный и настраиваемый рейтинг релевантности. nickdos
@nickdos да, счет предварительно рассчитан. И я думаю, что вы правы, сложная часть состоит в большом количестве атрибутов. Я не знаю, как Mongodb справится с этим. Создает ли он один индекс для атрибутов? Можно ли даже иметь столько индексов? В любом случае мы собираемся провести тестирование, но я хотел бы убедиться, что мы не пропустили правильную стратегию. log0
Миллионы предметов не проблема для SOLR, но 10 000 возможных атрибутовcould быть проблемой. SOLR поддерживает динамические поля, так что вам не нужно определять все атрибуты, но память может вырваться с широкой / разреженной схемой? Другие могут посоветовать это лучше. nickdos

Ваш Ответ

3   ответа
2

Это именно то, что Монго может иметь дело с. Здесь помогает тот факт, что ваши атрибуты имеют логический тип. Возможная схема приведена ниже:

[
    {
        true_tags:[attr1, attr2, attr3, ...],
        false_tags: [attr4, attr5, attr6, ...]
    },
]

Тогда мы можем индексировать наtrue_tags а такжеfalse_tags, И это должно быть эффективно для поиска с $ in, $ all, ... операторами запроса.

Извините, это было не очень понятно, но под логическим значением я имел в виду, что либо элемент имеет атрибут, либо нет. Ваш ответ остается в силе, но я ищу более точную информацию. Есть ли ограничения на этот вид индекса (кажется, что есть размер ключа, максимальное количество индекса и т. Д., Но, возможно, моя информация устарела)? как это работает с шардингом? log0
2

Redis был бы идеальным кандидатом на

  • "the top n items" for "millions of items ordered by score"

Redis имеет встроенную структуру данных, с которой вы можете начать:Sorted Set = & GT; каждый член отсортированного набора связан с оценкой. Который, например, может быть ранжирован по баллу сZRANGEBYSCORE:

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

Я призываю вас взглянуть на отсортированный наборкоманды и почувствуйте Redis, поскольку ваша проблема (как об этом говорится) просит об этом. Конечно, вы можете хранить столько атрибутов, сколько захотите, в одном элементе Set.


Что касается MongoDB, так как вы упомянули миллионы, если вы не можете изгибать инкрементные запросы для решения вашей проблемы, я быnot ожидать ответ второй секунды.

Как упомянул @nickdos, Solr Relevancy - довольно мощная функция, но количество атрибутовwill быть проблемой, так как он должен был бы хранить все эти атрибуты в памяти для каждого элемента. Хотя дюжина для каждого, возможно, не так уж и плоха = & gt; просто попробуй и посмотри.

9

Mongodb может обработать то, что вы хотите, если вы храните свои объекты, как это

{ score:2131, attributes: ["attr1", "attr2", "attr3"], ... }

Тогда следующий запрос будет соответствовать всем элементам, которые имеют att1 и attr2

c = db.mycol.find({ attributes: { $all: [ "attr1", "attr2" ] } })

но это не будет соответствовать

c = db.mycol.find({ attributes: { $all: [ "attr1", "attr4" ] } })

запрос возвращает курсор, если вы хотите, чтобы этот курсор был отсортирован, просто добавьте параметры сортировки в запрос следующим образом

c = db.mycol.find({ attributes: { $all: [ "attr1", "attr2" ] }}).sort({score:1})

Посмотри наРасширенные запросы чтобы увидеть, что возможно.

Соответствующие индексы можно настроить следующим образом

db.mycol.ensureIndex({attributes:1, score:1})

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

db.mycol.find({ attributes: { $all: [ "attr1" ] }}).explain()

Монго объясняет, сколько объектов было отсканировано, сколько времени заняла операция и другая различная статистика.

Хорошо, я понимаю, один индекс, но один и тот же документ индексируется несколько раз, по одному разу для каждого значения в мультиключе. log0
Я где-то читал, что в коллекции может быть максимум 64 индекса. Что происходит в случае индексированного массива? Значит ли это, что монго создаст 10 000 индексов? log0
Индекс, созданный в этом ответе, представляет собой один индекс с несколькими ключами. «Оценка» был последний ключ, потому что только последний ключ может быть использован для сортировки. Когда массив индексируется, каждый элемент массива добавляется в индекс. Это означает, что при выполнении запроса, упомянутого выше, несколько узлов должны быть отсканированы, чтобы убедиться, что они соответствуют запросу.
Действительно, кажется, mongodb очень хорошо подходит для этой цели, но я беспокоюсь об эффективности. Вы не упомянули индексы здесь. Достаточно ли в моем случае индекса по атрибутам и оценкам ... log0
Я добавил информацию об индексах. Убедитесь, что все ваши индексы помещаются в память, иначе ваши запросы будут выполняться медленно.

Похожие вопросы