Как отфильтровать огромный список идентификаторов из Solr во время выполнения

У меня есть индекс для продуктов - Solr. Мне нужно предоставить индивидуальный список продуктов для каждого покупателя, так что я должен исключить некоторые конкретные продукты для каждого покупателя. В настоящее время я сохраняю эти отношения клиентов и исключенных продуктов в базе данных SQL, а затем фильтрую их в Solr с помощью запроса условий. Есть ли способ сохранить эти отношения в самом Solr, чтобы мне не приходилось каждый раз вычислять список исключений сначала из SQL.

Что-то очень похожее на то, что мы можем сделать в elasticsearch, используя https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html

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

  1. Ведение списка клиентов в самом индексе продуктов и фильтрация по нему. Но это будет действительно больно, если мне придется переиндексировать все документы. Также список может быть огромным.

  2. Другой способ, который я мог придумать, - это поддерживать отдельное ядро ​​для хранения документов для каждого клиента и исключить product_id, а также выполнить соединение с помощью {! Join} для фильтрации продуктов для клиента. Это масштабируемое решение.

Каким должен быть идеальный подход для хранения таких данных в Solr.


person sagar agarwal    schedule 29.09.2017    source источник


Ответы (2)


Есть ли проблемы с производительностью базы данных SQL? Совершенно нормально запросить БД, получить идентификаторы и отправить их в Solr. Вы избежите сложности и дублирования данных. В любом случае вам придется выполнить некоторые вычисления, чтобы отправить эти идентификаторы в Solr.

Но чтобы ответить на ваш вопрос, да, вы действительно можете сохранить идентификаторы исключенных продуктов для каждого клиента в отдельном индексе. Вы бы использовали многозначное поле и обновляли с помощью атомарные обновления. Если вы это сделаете, убедитесь, что схема индексирования проста и не используется анализатор идентификаторов (просто используйте тип string без токенизатора или фильтра).

Вам не нужно выполнять запрос соединения Solr. Вам нужно только найти идентификаторы продуктов для каждого клиента (1-й запрос) и обработать их как CSV, а затем выполнить terms query с идентификаторами продуктов, полученными из индекса (2-й запрос).

person drjz    schedule 29.09.2017
comment
Спасибо за ответ здесь. Я думаю, что буду использовать только подход SQL. Будет фильтровать запросы с использованием идентификаторов. - person sagar agarwal; 06.10.2017

Вам нужно найти для себя лучший компромисс

Лучшее время выполнения запроса. Вы добавляете поле (многозначное) в индекс продукта: allowed_users (или disabled_users) в зависимости от количества элементов (которое вы хотите минимизировать). Это потребует повторной индексации в первый раз и обновления индекса для каждого изменения разрешений пользователя. Чтобы уменьшить сетевой трафик и оптимизировать обновления, вы можете взглянуть на атомарные обновления [1].

Наилучшие показатели времени индексирования. Если предыдущий подход неосуществим в вашем случае или вас не устраивает, вы можете попытаться оптимизировать сторону индексирования. Вы можете проиндексировать документ в отдельной коллекции:

<Id>
<product_id>
<user_id>

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

В общем, вы уже подумали об обеих идеях :)

[1] https://lucene.apache.org/solr/guide/6_6/updating-parts-of-documents.html

person Alessandro Benedetti    schedule 02.10.2017