Elasticsearch 数据分析:聚合 (Aggregations) Elasticsearch 数据分析:聚合 (Aggregations) 6.1 聚合的基本概念 聚合是在搜索查询上下文中定义的,它们会针对与查询匹配的文档集进行计算。 聚合可以嵌套,允许我们构建复杂的多级分析。 聚合的类型: Elasticsearch 提供了多种聚合类型,可以分为以下几类: 指标聚合 (Metrics Aggregations): 计算字段的统计指标,如平均值、最大值、最小值、总和等。 桶聚合 (Bucket Aggregations): 将文档分组到不同的桶中,例如按日期范围、地理位置、关键词等。
聚合是在搜索查询上下文中定义的,它们会针对与查询匹配的文档集进行计算。 聚合可以嵌套,允许我们构建复杂的多级分析。
聚合的类型:
Elasticsearch 提供了多种聚合类型,可以分为以下几类:
指标聚合 (Metrics Aggregations): 计算字段的统计指标,如平均值、最大值、最小值、总和等。
桶聚合 (Bucket Aggregations): 将文档分组到不同的桶中,例如按日期范围、地理位置、关键词等。
管道聚合 (Pipeline Aggregations): 基于其他聚合的结果进行计算,例如计算移动平均值、百分比变化等。
矩阵聚合 (Matrix Aggregations): 执行多个字段之间的矩阵计算。
聚合的结构:
一个聚合通常包含以下部分:
name: 聚合的名称,用于在响应中标识结果。
type: 聚合的类型,如 terms, range, avg 等。
field: 要聚合的字段。
子聚合 (Sub-aggregations): 嵌套在当前聚合中的其他聚合。
指标聚合计算字段的统计指标。 常见的指标聚合包括:
avg: 计算平均值。
max: 计算最大值。
min: 计算最小值。
sum: 计算总和。
count: 计算文档数量(通常不需要显式指定,因为桶聚合会返回文档数量)。
stats: 返回多个统计指标(min, max, avg, sum, count)。
extended_stats: 返回更详细的统计指标,包括标准差、方差等。
percentiles: 计算百分位数。
cardinality: 计算唯一值的数量。
代码示例:
假设我们有一个名为 products 的索引,其中包含以下字段:
name: 产品名称
price: 产品价格
category: 产品类别
以下是如何使用 avg 聚合计算所有产品的平均价格:
GET products/_search { "size": 0, "aggs": { "average_price": { "avg": { "field": "price" } } } }
响应示例:
{ "took": 3, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1000, "max_score": 0.0, "hits": [] }, "aggregations": { "average_price": { "value": 55.50 } } }
以下是如何使用 stats 聚合同时计算 price 字段的多个统计指标:
GET products/_search { "size": 0, "aggs": { "price_stats": { "stats": { "field": "price" } } } }
响应示例:
{ "took": 2, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1000, "max_score": 0.0, "hits": [] }, "aggregations": { "price_stats": { "count": 1000, "min": 10.0, "max": 100.0, "avg": 55.5, "sum": 55500.0 } } }
桶聚合将文档分组到不同的桶中。 常见的桶聚合包括:
terms: 按字段的值进行分组。
range: 按数值范围进行分组。
date_range: 按日期范围进行分组。
histogram: 按数值间隔进行分组。
date_histogram: 按日期间隔进行分组。
geo_distance: 按地理距离进行分组。
代码示例:
以下是如何使用 terms 聚合按 category 字段对产品进行分组,并统计每个类别的产品数量:
GET products/_search { "size": 0, "aggs": { "categories": { "terms": { "field": "category" } } } }
响应示例:
{ "took": 4, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1000, "max_score": 0.0, "hits": [] }, "aggregations": { "categories": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "Electronics", "doc_count": 350 }, { "key": "Clothing", "doc_count": 300 }, { "key": "Books", "doc_count": 200 }, { "key": "Home", "doc_count": 150 } ] } } }
以下是如何使用 range 聚合按价格范围对产品进行分组:
GET products/_search { "size": 0, "aggs": { "price_ranges": { "range": { "field": "price", "ranges": [ { "to": 20 }, { "from": 20, "to": 50 }, { "from": 50 } ] } } } }
响应示例:
{ "took": 3, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1000, "max_score": 0.0, "hits": [] }, "aggregations": { "price_ranges": { "buckets": [ { "key": "*-20.0", "to": 20.0, "doc_count": 200 }, { "key": "20.0-50.0", "from": 20.0, "to": 50.0, "doc_count": 300 }, { "key": "50.0-*", "from": 50.0, "doc_count": 500 } ] } } }
聚合可以嵌套,允许我们构建复杂的多级分析。 例如,我们可以先按类别分组,然后在每个类别中计算平均价格。
代码示例:
GET products/_search { "size": 0, "aggs": { "categories": { "terms": { "field": "category" }, "aggs": { "average_price": { "avg": { "field": "price" } } } } } }
响应示例:
{ "took": 5, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1000, "max_score": 0.0, "hits": [] }, "aggregations": { "categories": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "Electronics", "doc_count": 350, "average_price": { "value": 70.0 } }, { "key": "Clothing", "doc_count": 300, "average_price": { "value": 40.0 } }, { "key": "Books", "doc_count": 200, "average_price": { "value": 25.0 } }, { "key": "Home", "doc_count": 150, "average_price": { "value": 60.0 } } ] } } }
Mermaid 图表:
以下是一个使用 mermaid 绘制的嵌套聚合的结构图:
管道聚合基于其他聚合的结果进行计算。 常见的管道聚合包括:
derivative: 计算导数(变化率)。
moving_avg: 计算移动平均值。
cumulative_sum: 计算累计总和。
bucket_script: 使用脚本计算自定义指标。
代码示例:
假设我们有一个包含每日销售额数据的索引,我们可以使用 date_histogram 聚合按日期分组,然后使用 moving_avg 聚合计算 7 天的移动平均值。
GET sales/_search { "size": 0, "aggs": { "sales_over_time": { "date_histogram": { "field": "date", "interval": "day" }, "aggs": { "total_sales": { "sum": { "field": "amount" } }, "moving_average": { "moving_avg": { "buckets_path": "total_sales", "window": 7 } } } } } }
Elasticsearch 的聚合功能为我们提供了强大的数据分析能力。 通过灵活组合各种聚合类型,我们可以从数据中提取有价值的见解。 本文介绍了指标聚合、桶聚合、嵌套聚合和管道聚合的基本概念和用法,并通过代码示例详细说明。 掌握这些知识,可以帮助您更好地利用 Elasticsearch 进行数据分析。
希望这篇文章对您有所帮助!