https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-composite-aggregation.html#_pagination
当需要分页查询大量的桶时composite 聚合可以通过分页的方式逐步获取桶结果,避免一次性返回大量的桶 。
与传统分页方法不同,composite aggregation 并不基于结果的偏移量(offset),而是基于聚合桶的游标机制来实现分页,从而避免了性能瓶颈。
composite aggregation 是 Elasticsearch 中的一种特殊聚合方式,适用于需要分页展示的聚合结果。它与传统的聚合方式不同,采用了基于游标的分页模型。composite aggregation 不依赖 from 和 size 来进行分页,而是通过 after 参数来指定从某个特定桶之后开始返回数据,从而实现分页。
假设我们有一个索引,名称为 your_index_name,其中包含多个文档,每个文档都有一个字段 your_field_name。我们希望根据这个字段进行分页查询,并且每次返回 10 个聚合结果。
以下是一个基础的分页查询示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
GET /your_index_name/_search { "size": 0, "aggs": { "my_composite_agg": { "composite": { "size": 10, "sources": [ { "my_terms_agg": { "terms": { "field": "your_field_name" } } } ] } } } } |
要实现分页,我们需要使用 after 参数来指示从哪个位置开始返回数据。这个参数的值是上一个查询返回的最后一个桶的 key 值。
下面是如何获取第二页结果的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
GET /your_index_name/_search { "size": 0, "aggs": { "my_composite_agg": { "composite": { "size": 10, "after": ["bucket_key_from_first_page"], // 第一页的最后一个桶的key值 "sources": [ { "my_terms_agg": { "terms": { "field": "your_field_name" } } } ] } } } } |
例如,假设第一次查询的返回结果包含以下聚合信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
{ "aggregations": { "my_composite_agg": { "buckets": [ { "key": { "your_field_name": "value1" }, "doc_count": 10 }, { "key": { "your_field_name": "value2" }, "doc_count": 15 }, // ... 更多桶 ], "after_key": { "your_field_name": "value2" } } } } |
在第二次分页查询时,我们需要使用 after_key 中的 your_field_name: "value2" 作为 after 参数的值,以此来获取下一页的结果。
官方案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
GET /_search { "size": 0, "aggs": { "my_buckets": { "composite": { "size": 2, "sources": [ { "date": { "date_histogram": { "field": "timestamp", "calendar_interval": "1d" } } }, { "product": { "terms": { "field": "product" } } } ] } } } } |
返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
{ ... "aggregations": { "my_buckets": { "after_key": { "date": 1494288000000, "product": "mad max" }, "buckets": [ { "key": { "date": 1494201600000, "product": "rocky" }, "doc_count": 1 }, { "key": { "date": 1494288000000, "product": "mad max" }, "doc_count": 2 } ] } } } |
下次查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
GET /_search { "size": 0, "aggs": { "my_buckets": { "composite": { "size": 2, "sources": [ { "date": { "date_histogram": { "field": "timestamp", "calendar_interval": "1d", "order": "desc" } } }, { "product": { "terms": { "field": "product", "order": "asc" } } } ], "after": { "date": 1494288000000, "product": "mad max" } } } } } |
composite aggregation 非常适用于以下场景: