Показать все результаты / сегменты агрегации Elasticsearch, а не только 10


166

Я пытаюсь перечислить все сегменты в агрегации, но, кажется, показывает только первые 10.

Мой поиск:

curl -XPOST "http://localhost:9200/imoveis/_search?pretty=1" -d'
{
   "size": 0, 
   "aggregations": {
      "bairro_count": {
         "terms": {
            "field": "bairro.raw"
         }
      }
   }
}'

Возвращает:

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 16920,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "bairro_count" : {
      "buckets" : [ {
        "key" : "Barra da Tijuca",
        "doc_count" : 5812
      }, {
        "key" : "Centro",
        "doc_count" : 1757
      }, {
        "key" : "Recreio dos Bandeirantes",
        "doc_count" : 1027
      }, {
        "key" : "Ipanema",
        "doc_count" : 927
      }, {
        "key" : "Copacabana",
        "doc_count" : 842
      }, {
        "key" : "Leblon",
        "doc_count" : 833
      }, {
        "key" : "Botafogo",
        "doc_count" : 594
      }, {
        "key" : "Campo Grande",
        "doc_count" : 456
      }, {
        "key" : "Tijuca",
        "doc_count" : 361
      }, {
        "key" : "Flamengo",
        "doc_count" : 328
      } ]
    }
  }
}

У меня есть более 10 ключей для этой агрегации. В этом примере у меня будет 145 ключей, и я хочу подсчитать для каждого из них. Есть ли пагинация на ведрах? Могу ли я получить их все?

Я использую Elasticsearch 1.1.0

Ответы:


196

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

curl -XPOST "http://localhost:9200/imoveis/_search?pretty=1" -d'
{
   "size": 0,
   "aggregations": {
      "bairro_count": {
         "terms": {
            "field": "bairro.raw",
             "size": 0
         }
      }
   }
}'

Как уже упоминалось в документе, работает только для версии 1.1.0 и выше

редактировать

Обновление ответа на основе комментария @PhaedrusTheGreek.

установка size:0устарела в версии 2.x и далее из-за проблем с памятью, вызванных для вашего кластера со значениями полей с высокой мощностью. Вы можете прочитать больше об этом в выпуске github здесь .

Рекомендуется явно установить разумное значение для sizeчисла от 1 до 2147483647.


8
Обратите внимание, что установка size: 0 теперь устарела из-за проблем с памятью, вызванных для вашего кластера со значениями полей с большим количеством элементов. github.com/elastic/elasticsearch/issues/18838 . Вместо этого используйте действительное, разумное число от 1 до 2147483647.
PhaedrusTheGreek

спасибо @PhaedrusTheGreek за указание на это, я отредактировал ответ, чтобы включить ваш комментарий.
Кити

0 работает на 2.5.2. что вы имеете в виду под 2.x вперед? ты имеешь ввиду после 5 версии? Мне также любопытно, какие проблемы с памятью могут возникнуть, если я хочу вернуть все возможные агги, в чем разница между настройкой 0 (max_value) и 10000 (какой-то большой верхний предел)?
batmaci

4
@batmaci устарела в 2.x, поэтому все равно будет работать и была удалена из 5.x
keety

@batmaci Я считаю, что использование size: <big number> не менее требовательно к памяти, но просто делает для клиента более очевидным, что производительность снижается. Я думаю, что это аргумент в пользу обесценивания size:0. Вы можете прочитать об этом больше в этом выпуске
keety

37

Как показать все ведра?

{
  "size": 0,
  "aggs": {
    "aggregation_name": {
      "terms": {
        "field": "your_field",
        "size": 10000
      }
    }
  }
}

Заметка

  • "size":10000Получите максимум 10000 ведер. По умолчанию 10.

  • "size":0В результате "hits"содержит 10 документов по умолчанию. Нам они не нужны.

  • По умолчанию сегменты упорядочены по doc_countубыванию.


Почему я получаю Fielddata is disabled on text fields by defaultошибку?

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

Итак, вместо того, чтобы писать, "field": "your_field"вам нужно иметь "field": "your_field.keyword".


Влияет ли наличие большего размера сегментов на производительность (время выполнения запроса) эластичного поискового запроса?
user3522967

Как мы можем добавить нумерацию страниц для ведер?
Miind

7

Увеличьте размер (2-й размер) до 10000 в вашей совокупности терминов, и вы получите контейнер размером 10000. По умолчанию он установлен на 10. Также, если вы хотите увидеть результаты поиска, просто установите 1-й размер на 1, вы можете см. 1 документ, поскольку ES поддерживает поиск и агрегацию.

curl -XPOST "http://localhost:9200/imoveis/_search?pretty=1" -d'
{
   "size": 1,
   "aggregations": {
      "bairro_count": {
         "terms": {
             "field": "bairro.raw",
             "size": 10000

         }
      }
   }
}'

4

Если вы хотите , чтобы получить все уникальные значения , не устанавливая магическое число ( size: 10000), а затем использовать КОМПОЗИТНУЮ агрегацию (ES 6.5+) .

Из официальной документации :

«Если вы хотите извлечь все термины или все комбинации терминов в агрегации вложенных терминов, вам следует использовать КОМПОЗИЦИЮ СОСТАВЛЕНИЯ, которая позволяет разбивать на страницы по всем возможным терминам, а не устанавливать размер, превышающий количество элементов поля в агрегации терминов. Агрегирование терминов предназначено для возврата верхних терминов и не допускает разбиение на страницы. "

Пример реализации в JavaScript:

const ITEMS_PER_PAGE = 1000;

const body =  {
    "size": 0, // Returning only aggregation results: https://www.elastic.co/guide/en/elasticsearch/reference/current/returning-only-agg-results.html
    "aggs" : {
        "langs": {
            "composite" : {
                "size": ITEMS_PER_PAGE,
                "sources" : [
                    { "language": { "terms" : { "field": "language" } } }
                ]
            }
        }
     }
};

const uniqueLanguages = [];

while (true) {
  const result = await es.search(body);

  const currentUniqueLangs = result.aggregations.langs.buckets.map(bucket => bucket.key);

  uniqueLanguages.push(...currentUniqueLangs);

  const after = result.aggregations.langs.after_key;

  if (after) {
      // continue paginating unique items
      body.aggs.langs.composite.after = after;
  } else {
      break;
  }
}

console.log(uniqueLanguages);

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.