Mostrar todos os resultados / agregações de agregação da Elasticsearch e não apenas 10

165

Estou tentando listar todos os buckets em uma agregação, mas parece estar mostrando apenas os 10 primeiros.

Minha pesquisa:

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

Devoluções:

{
  "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
      } ]
    }
  }
}

Eu tenho muito mais que 10 chaves para essa agregação. Neste exemplo, eu teria 145 chaves e quero a contagem para cada uma delas. Existe alguma paginação nos baldes? Posso pegar todos eles?

Estou usando o Elasticsearch 1.1.0

Samuel Rizzo
fonte

Respostas:

196

O parâmetro tamanho deve ser um parâmetro para o exemplo de consulta de termos:

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

Conforme mencionado no documento, funciona apenas para a versão 1.1.0 em diante

Editar

Atualizando a resposta com base no comentário @PhaedrusTheGreek.

A configuração size:0foi preterida na 2.x em diante, devido a problemas de memória infligidos no cluster com valores de campo de alta cardinalidade. Você pode ler mais sobre isso na edição do github aqui .

É recomendável definir explicitamente um valor razoável para sizeum número entre 1 e 2147483647.

keety
fonte
8
Observe que a configuração size: 0 agora está obsoleta, devido a problemas de memória infligidos no cluster com valores de campo de alta cardinalidade. github.com/elastic/elasticsearch/issues/18838 . Em vez disso, use um número real, razoável entre 1 a 2147483647.
PhaedrusTheGreek
obrigado @PhaedrusTheGreek por apontar isso, editei a resposta para incorporar seu comentário.
keety
0 está funcionando no 2.5.2. o que você quer dizer com 2.x em diante? você quer dizer após a versão 5? Também estou curioso para saber que tipo de problemas de memória isso pode causar se eu quiser retornar todos os possíveis possíveis. Qual seria a diferença entre a configuração 0 (valor_máximo) e 10000 (algum grande limite superior)?
batmaci
4
@batmaci foi depreciado em 2.x isso seria ainda trabalho e foi retirada do 5.x
keety
@batmaci Acredito que o uso do tamanho: <big number> não consome menos memória, mas apenas torna mais explícito para o cliente que existe um custo de desempenho. Eu acho que esse é o raciocínio por trás da depreciação size:0. Você pode ler mais sobre isso neste github questão
keety
37

Como mostrar todos os baldes?

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

Nota

  • "size":10000Obtenha no máximo 10.000 baldes. O padrão é 10.

  • "size":0Como resultado, "hits"contém 10 documentos por padrão. Nós não precisamos deles.

  • Por padrão, os buckets são ordenados pelo doc_countem ordem decrescente.


Por que recebo Fielddata is disabled on text fields by defaulterro?

Como fielddata está desativado nos campos de texto por padrão . Se você não escolheu um mapeamento de tipo de campo, ele possui os mapeamentos dinâmicos padrão para os campos de sequência .

Então, em vez de escrever, "field": "your_field"você precisa ter "field": "your_field.keyword".

kgf3JfUtW
fonte
O tamanho maior de buckets afeta o desempenho (tempo para executar a consulta) da consulta de pesquisa elástica?
user3522967 21/01
Como podemos adicionar paginação para os buckets?
Miind 28/02
7

Aumente o tamanho (2º tamanho) para 10000 em suas agregações de termos e você obterá o intervalo de tamanho 10000. Por padrão, é definido como 10. Além disso, se você deseja ver os resultados da pesquisa, basta fazer o 1º tamanho em 1, você pode consulte 1 documento, pois o ES oferece suporte à pesquisa e agregação.

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

         }
      }
   }
}'
maravilha
fonte
3

Se você deseja obter todos os valores exclusivos sem definir um número mágico ( size: 10000), use COMPOSITE AGGREGATION (ES 6.5+) .

Da documentação oficial :

"Se você deseja recuperar todos os termos ou todas as combinações de termos em uma agregação de termos aninhados, use a COMPOSITE AGGREGATION que permite paginar todos os termos possíveis em vez de definir um tamanho maior que a cardinalidade do campo na agregação de termos. A agregação de termos deve retornar os principais termos e não permite a paginação ".

Exemplo de implementação em 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);

Ilarion Halushka
fonte