显示所有 Elasticsearch 聚合结果/桶,而不仅仅是 10 个

Posted

技术标签:

【中文标题】显示所有 Elasticsearch 聚合结果/桶,而不仅仅是 10 个【英文标题】:Show all Elasticsearch aggregation results/buckets and not just 10 【发布时间】:2014-05-20 13:30:08 【问题描述】:

我正在尝试列出聚合中的所有存储桶,但它似乎只显示前 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

【问题讨论】:

【参考方案1】:

大小参数应该是术语查询示例的参数:

curl -XPOST "http://localhost:9200/imoveis/_search?pretty=1" -d'

   "size": 0,
   "aggregations": 
      "bairro_count": 
         "terms": 
            "field": "bairro.raw",
             "size": 10000
         
      
   
'

size: 0 用于 ES 版本 2 及之前的版本。

设置 size:0 在 2.x 及以后版本中已弃用,因为具有高基数字段值的集群会出现内存问题。您可以在 github issue here 中阅读更多相关信息。

建议为size 显式设置一个介于1 到2147483647 之间的合理值。

【讨论】:

请注意,现在不推荐设置 size:0,因为高基数字段值会在集群上造成内存问题。 github.com/elastic/elasticsearch/issues/18838。相反,请使用 1 到 2147483647 之间的一个合理的实数。 感谢@PhaedrusTheGreek 指出这一点,我已经编辑了答案以纳入您的评论。 0 正在开发 2.5.2。 2.x 以后是什么意思?你的意思是在版本5之后?我也很好奇如果我想返回所有可能的 aggs 会导致什么样的内存问题,设置 0(最大值)和 10000(一些大的上限)有什么区别? @batmaci 它在 2.x 中已被弃用,因此仍然可以使用并已从 5.x 中删除 @batmaci 我相信 size: 的使用并没有减少内存密集型,而是让客户更清楚地知道存在性能成本。我认为这就是弃用size:0 背后的原因。您可以在此 github issue 中了解更多信息【参考方案2】:

如何显示所有的桶?


  "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 错误?

因为fielddata is disabled on text fields by default。如果您没有明确选择字段类型映射,则它具有default dynamic mappings for string fields。

所以,你需要有"field": "your_field.keyword",而不是写"field": "your_field"

【讨论】:

桶的大小是否会影响弹性搜索查询的性能(运行查询的时间)? 如何为桶添加分页? @AmirAfianian documentation for the composite aggregation 解释了这一点。【参考方案3】:

如果您想在不设置幻数 (size: 10000) 的情况下获得所有唯一值,请使用 COMPOSITE AGGREGATION (ES 6.5+)

来自official documentation:

“如果您想检索嵌套术语聚合中的所有术语或术语的所有组合您应该使用 COMPOSITE AGGREGATION,它允许对所有可能的术语进行分页而不是设置大小大于 terms 聚合中字段的基数。terms 聚合旨在返回顶部术语,不允许分页。”

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);

【讨论】:

【参考方案4】:

在您的术语聚合中将大小(第二个大小)增加到 10000,您将获得大小为 10000 的存储桶。默认情况下,它设置为 10。 另外,如果你想看搜索结果,只需将 1st size 设置为 1,你可以看到 1 个文档,因为 ES 确实支持搜索和聚合。

curl -XPOST "http://localhost:9200/imoveis/_search?pretty=1" -d'

   "size": 1,
   "aggregations": 
      "bairro_count": 
         "terms": 
             "field": "bairro.raw",
             "size": 10000

         
      
   
'

【讨论】:

以上是关于显示所有 Elasticsearch 聚合结果/桶,而不仅仅是 10 个的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch 聚合按每个存储桶的前一个结果进行过滤

Elasticsearch 聚合后排序 --- 2022-04-03

elasticsearch聚合操作——本质就是针对搜索后的结果使用桶bucket(允许嵌套)进行group by,统计下分组结果,包括min/max/avg

elasticsearch——部分聚合结果不准确

elasticsearch 聚合对存储桶键进行排序

elasticsearch系列六:聚合分析(聚合分析简介指标聚合桶聚合)