Как в Elasticsearch получить продукты, сгруппированные по магазину, который их продает? - PullRequest
0 голосов
/ 10 июля 2020

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

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

Например, предположим, что у меня есть следующие данные:

  • Магазин 1
    • Товар 1a, описание: «Бутерброд с арахисовым маслом и желе»
    • Товар 1b , описание: «Тако»
    • Товар 1 c, описание: «Держатель для сэндвичей»
  • Магазин 2
    • Товар 2а, описание: " Чаша для буррито "
  • Магазин 3
    • Товар 3a, описание:« Сэндвичница »
    • Товар 3b, описание:« Сэндвич-хлеб »
    • Продукт 3 c, описание: «Щипцы для салата»

В моем общем приложении я хочу, чтобы запрос для «бутерброда» возвращал что-то вроде:

  • Магазин 1
    • продукт 1a
    • продукт 1 c
  • Магазин 3
    • продукт 3a
    • product 3b

Всякий раз, когда я показываю магазин, я всегда хочу показать все хитов для этого магазина. В домене, в котором я работаю, много магазинов, но в каждом магазине только небольшое количество товаров (максимум около 10-20, в большинстве магазинов только 2 или 3).

Я могу вижу два способа реализовать это, и оба они кажутся мне плохими.

Подход №1

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

  • Я не могу использовать какой-либо вид ранжирования, поскольку собираюсь пересортировать результаты.
  • Я тоже могу ' не делать никаких ограничений; Я должен получить каждый документ, независимо от того, сколько их может быть, поскольку в противном случае я не могу гарантировать, что у меня есть все продукты для конкретного магазина. Это приведет к большим потерям работы.

Подход № 2

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

  • Я прошу elasticsearch выполнить больше работы, чем необходимо; внутри он нашел все, что мне нужно, в первом запросе, но я все равно прошу второй запрос
  • Выполнение двух связанных запросов усложняет код и требует от меня синхронизировать два запроса c (например, я необходимо убедиться, что документы, сопоставленные в запросе 1 как подполя, являются теми же документами, которые соответствуют запросу 2)

Может ли кто-нибудь более опытный с Elasticsearch, чем я, найти лучший вариант?

1 Ответ

1 голос
/ 10 июля 2020

С Подходом №2 я вижу 2 варианта:

  1. Вложенные внутренние обращения .

  2. Вы можете использовать top_hits с агрегатором reverse_nested . Вы будете искать продукты в запросе и сгруппируете документы по магазинам в агрегаторе. Агрегация top_hits возвращает обычные результаты поиска, что означает, что вы получите дочерние элементы (продукты) вместе с родительским (магазином).

...