相关技巧
主页 > 网络编程 > 相关技巧 >

ElasticSearch使用Composite Aggregation实现桶的分页查询功能

2024-12-13 | 佚名 | 点击:

官方文档

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-composite-aggregation.html#_pagination

概述

当需要分页查询大量的桶时composite 聚合可以通过分页的方式逐步获取桶结果,避免一次性返回大量的桶 。

与传统分页方法不同,composite aggregation 并不基于结果的偏移量(offset),而是基于聚合桶的游标机制来实现分页,从而避免了性能瓶颈。

Composite Aggregation 概述

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 非常适用于以下场景:

注意事项

原文链接:
相关文章
最新更新