Сортировка продуктов с выбором товаров от каждого бренда и список соответственно - PullRequest
1 голос
/ 06 марта 2020

У меня есть 10 продуктов с разными брендами. Brand1 содержит 3 продукта. Brand2 содержит 4 продукта. Brand3 содержит 3 продукта.

В настоящее время я получаю вывод в соответствии с сортировкой по релевантности (приведенный ниже пример)

{
    'id': 1,
    'name': 'product1',
    'brand': 'brand3',
},{
    'id': 3,
    'name': 'product3',
    'brand': 'brand2',
},{
    'id': 13,
    'name': 'product3',
    'brand': 'brand1',
},{
    'id': 2,
    'name': 'product4',
    'brand': 'brand3',
},{
    'id': 5,
    'name': 'product5',
    'brand': 'brand2',
},{
    'id': 9,
    'name': 'product6',
    'brand': 'brand3',
},{
    'id': 17,
    'name': 'product7',
    'brand': 'brand2',
},{
    'id': 20,
    'name': 'product12',
    'brand': 'brand2',
},{
    'id': 23,
    'name': 'product15',
    'brand': 'brand1',
},{
    'id': 7,
    'name': 'product10',
    'brand': 'brand1',
}

Теперь, что я хочу, так, как показано ниже. Сортируйте товары согласно выбранному 1 продукту от каждого бренда, а затем следующие 1 продукт от каждого бренда и так далее (согласно приведенному ниже примеру). И да, еще одна важная вещь. Я также хочу добавить нумерацию страниц к этому выводу.

{
    'id': 13,
    'name': 'product3',
    'brand': 'brand1',
},{
    'id': 3,
    'name': 'product3',
    'brand': 'brand2',
},{
    'id': 1,
    'name': 'product1',
    'brand': 'brand3',
},{
    'id': 23,
    'name': 'product15',
    'brand': 'brand1',
},{
    'id': 5,
    'name': 'product5',
    'brand': 'brand2',
},{
    'id': 2,
    'name': 'product4',
    'brand': 'brand3',
},{
    'id': 7,
    'name': 'product10',
    'brand': 'brand1',
},{
    'id': 17,
    'name': 'product7',
    'brand': 'brand2',
},{
    'id': 9,
    'name': 'product6',
    'brand': 'brand3',
},{
    'id': 20,
    'name': 'product12',
    'brand': 'brand2',
}

1 Ответ

1 голос
/ 06 марта 2020

Один из способов - использовать TermAggregation для «brand», затем применить другой subAggregation к первой агрегации, а в это время использовать агрегацию сортировки сегментов в нужном поле.
Для получения более подробной информации, пожалуйста, проверьте это: c: https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-pipeline-bucket-sort-aggregation.html

Редактировать:
Предположим, что ваши данные похожи на: enter image description here

И сначала мы вызываем termAggregation в поле «brand», потому что это поле - то, что вы хотите правильно классифицировать ваши данные? Затем, основываясь на этой агрегации, мы вызываем другую субагрегацию (агрегацию по числу попаданий) при первой агрегации, чтобы получить нужные данные в более точной детализации. Таким образом, es dsl должен выглядеть следующим образом:

{
  "query": {
    "query_string": {
      "query": "*"
    }
  },
  "aggs": {
    "name": {
      "terms": {
        "field": "brand"
      },
      "aggs": {
        "name": {
          "top_hits": {
            "sort": [
              {
                "name": {
                  "id": "desc"
                }
              }
            ]
          }
        }
      }
    }
  }
}

Тогда вы получите возврат как enter image description here

Для удобства я просто установил размер как 1, чтобы дать вам более общий скриншот. И вы получаете и изменяете данные, которые вы хотите, из каждого сегмента под разным «брендом». Все, что вы хотите, как круговой или другой порядок.
А для разбивки на страницы вы можете сначала получить данные из es, а затем сделать логику разбивки на страницы c в своем собственном коде. SearchScroll поможет, если у вас много записей в ES. Поиск пакета записей, агрегирование по ним и переход к следующему пакету. Однако, в конце концов, ES больше похож на поисковик, чем на базу данных OLTP. Поддержка нумерации страниц немного ограничена в реализации из-за ее базового дизайна c. Так что не делайте никаких глубоких пагинаций ES! И будьте осторожны в использовании этих методов агрегирования, если размер ваших данных очень велик. Поскольку агрегации являются задачами с интенсивным использованием процессора и могут вызвать OOM и создать sh ваши кластеры es, если такие методы используются ненадлежащим образом.

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