当前位置: 首页 > 知识库问答 >
问题:

如何在Elasticsearch的聚合中添加分页

叶衡虑
2023-03-14

我有一个elasticsearch请求如下:

{
    "size":0,
    "aggs":{
        "group_by_state":{
            "terms":{
                "field":"poi_id"
            },
            "aggs":{
                "sum(price)":{
                    "sum":{
                        "field":"price"
                    }
                }
            }
        }
    }
}

我想在这个请求中添加分页,就像

select poi_id, sum(price) from table group by poi_id limit 0,2

我搜索了很多,找到了一个关于它的链接:https://github.com/elastic/elasticsearch/issues/4915.

但我仍然没有得到实现方法。

有没有办法通过Elasticsearch本身而不是我的应用程序来实现它?

共有3个答案

苍轶
2023-03-14

您可以在请求中使用来自和大小的参数。有关更多信息,请参阅https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-from-size.html。您的请求如下所示:

{
    "from" : 0, 
    "size" : 10,
    "aggs":{
        "group_by_state":{
            "terms":{
                "field":"poi_id"
            },
            "aggs":{
                "sum(price)":{
                    "sum":{
                        "field":"price"
                    }
                }
            }
        }
    }
}
谷良弼
2023-03-14

晚到派对,但刚刚在v6.3中发现了“复合”聚合。这些允许:
1。更像“Sql”的分组
2。使用“after\u键”分页<拯救了我们的一天,希望它也能帮助别人。

例如,在2个日期之间获得每小时命中视频数,按5个字段分组:

GET myindex-idx/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"docType": "myDOcType"}}, 
        {"range": {
          "@date": {"gte": "2019-06-19T21:00:00", "lt": "2019-06-19T22:00:00"}
          }
        }
      ]
    }
  }, 
  "size": 0, 
  "aggs": {
    "mybuckets": {
      "composite": {
        "size": 100, 
        "sources": [
          {"@date": {
            "date_histogram": {
              "field": "@date", 
              "interval": "hour", 
              "format": "date_hour"}
            }
          }, 
          {"field_1": {"terms": {"field": "field_1"}}}, 
          {"field_2": {"terms": {"field": "field_2"}}}, 
          {"field_3": {"terms": {"field": "field_3"}}}, 
          {"field_4": {"terms": {"field": "field_4"}}}, 
          {"field_5": {"terms": {"field": "field_5"}}}
        ]
      }
    }
  }
}

产生:

{
  "took": 255,
  "timed_out": false,
  "_shards": {
    "total": 80,
    "successful": 80,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 46989,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "mybuckets": {
      "after_key": {
        "@date": "2019-06-19T21",
        "field_1": 262,
        "field_2": 347,
        "field_3": 945,
        "field_4": 2258,
        "field_5": 0
      },
      "buckets": [
        {
          "key": {
            "@date": "2019-06-19T21",
            "field_1": 56,
            "field_2": 106,
            "field_3": 13224,
            "field_4": 46239,
            "field_5": 0
          },
          "doc_count": 3
        },
        {
          "key": {
            "@date": "2019-06-19T21",
            "field_1": 56,
            "field_2": 106,
            "field_3": 32338,
            "field_4": 76919,
            "field_5": 0
          },
          "doc_count": 2
        },
        ....

下面是这样发出的分页查询,使用“查询中的after\u key对象”after对象:

GET myindex-idx/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"docType": "myDOcType"}}, 
        {"range": {
          "@date": {"gte": "2019-06-19T21:00:00", "lt": "2019-06-19T22:00:00"}
          }
        }
      ]
    }
  }, 
  "size": 0, 
  "aggs": {
    "mybuckets": {
      "composite": {
        "size": 100, 
        "sources": [
          {"@date": {
            "date_histogram": {
              "field": "@date", 
              "interval": "hour", 
              "format": "date_hour"}
            }
          }, 
          {"field_1": {"terms": {"field": "field_1"}}}, 
          {"field_2": {"terms": {"field": "field_2"}}}, 
          {"field_3": {"terms": {"field": "field_3"}}}, 
          {"field_4": {"terms": {"field": "field_4"}}}, 
          {"field_5": {"terms": {"field": "field_5"}}}
        ],
      "after": {
        "@date": "2019-06-19T21",
        "field_1": 262,
        "field_2": 347,
        "field_3": 945,
        "field_4": 2258,
        "field_5": 0
        }
      }
    }
  }
}

这将遍历结果,直到mybuckets返回为空

郦祯
2023-03-14

目前,我正在研究分页聚合结果的解决方案。您要使用的是分区。官方文件中的这一部分非常有用。https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#_filtering_values_with_partitions

为了调整您的示例术语设置将更新如下。

{
    "size":0,
    "aggs":{
        "group_by_state":{
            "terms":{
                "field":"poi_id",
                "include": {
                    "partition": 0,
                    "num_of_partitions": 100
                },
                "size": 10000
            },
            "aggs":{
                "sum(price)":{
                    "sum":{
                        "field":"price"
                    }
                }
            }
        }
    }
}

这将把你的结果分成100个分区(num_of_partitions),每个分区的最大大小为10k个结果(size),并检索第一个这样的分区(分区: 0

如果要聚合的字段有超过10k个唯一值(并希望返回所有值),则需要增加值,或根据字段的基数动态计算分区的大小和数量。https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html#search-聚合度量基数聚合

您可能还想使用show\u term\u doc\u count\u error设置来确保聚合返回准确的计数。https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#_per_bucket_document_count_error

希望这有帮助。

 类似资料:
  • 是否有任何方法可以使用带聚合的弹性搜索进行分页?elasticsearch版本为2.3。以下是查询:

  • 问题内容: 想象一下,我有两种记录:一个存储桶和一个项目,其中存储在存储桶中的项目,而存储桶中的项目可能相对较少(通常不超过4个,从不超过10个)。这些记录被压缩为一个(具有更多存储桶信息的项目),并放置在Elasticsearch中。我要解决的任务是通过依赖项属性的过滤查询一次找到500个存储桶(最大),其中包含所有相关项,而我受困于限制/抵消聚合。我该如何执行此类任务?我看到聚合使我可以控制相

  • 问题内容: 我正在使用ElasticSearch 1.5.2,希望具有以下设置: 我应该在哪里添加它们?我的意思是在创建索引之前还是之后? 通过在线搜索,我发现了一些类似的方法 但是我有2个问题, 我收到编译错误:ImmutableSettings.builder类型的方法loadFromSource不适用于参数XContentBuilder 另外,我不知道如何将我的设置转换为这种格式。在哪里可以

  • 问题内容: 索引文件如下: 我想要的是按平台计数和输出统计信息。为了进行计数,我可以将术语聚合作为字段进行计数: 这样,我就可以像预期那样将统计数据作为多个存储桶接收到。 现在,我还能以某种方式添加到这些存储桶中吗(以及用于统计的漂亮输出)?我附带的最好的看起来像: 实际上,它可以工作,并且在每个存储桶中返回非常复杂的结构: 当然,可以从此结构中提取平台的名称和网址(例如),但是是否有更干净,更简

  • 索引文档如下: 我想要的是按平台计数和输出统计信息。对于计数,我可以使用带有的术语聚合作为字段进行计数: 通过这种方式,我以多个bucket的形式接收统计数据,看起来就像预期的那样{key:8,doc\u count:162511}。 现在,我可以以某种方式将和(用于漂亮的统计输出)添加到这些桶中吗?我带来的最好的看起来像: 实际上,它可以工作,并在每个桶中返回非常复杂的结构: 当然,平台的名称和

  • 框架集合由搜索查询选择的所有数据。框架中包含许多构建块,有助于构建复杂的数据描述或摘要。聚合的基本结构如下所示 - 有以下不同类型的聚合,每个都有自己的目的 - 指标聚合 这些聚合有助于从聚合文档的字段值计算矩阵,并且某些值可以从脚本生成。 数字矩阵或者是平均聚合的单值,或者是像一样的多值。 平均聚合 此聚合用于获取聚合文档中存在的任何数字字段的平均值。 例如, 请求正文 响应 如果该值不存在于一