Elasticsearch(ES)的聚合(Aggregation)功能类似于 SQL 中的 GROUP BY
+ 聚合函数
(如 COUNT、AVG、SUM),是进行统计分析的核心机制。
聚合(Aggregation)概述
Elasticsearch 的聚合分为三大类:
类别 | 说明 |
---|---|
Metric 聚合 | 计算数值(如:count、avg、sum、max、min) |
Bucket 聚合 | 类似于 SQL 的 GROUP BY ,把文档分类 |
Pipeline 聚合 | 对前面聚合结果再次聚合或计算(比如平均值的平均值) |
常见聚合类型详解
1️⃣ Bucket 聚合:分类统计
🔹 terms(词项分组)
用途:按字段值分组统计
{
"aggs": {
"group_by_tag": {
"terms": {
"field": "tag.keyword"
}
}
}
}
🔎 类似 SQL:
SELECT tag, COUNT(*) FROM table GROUP BY tag;
🔹 range(范围分组)
用途:按数值范围分组
{
"aggs": {
"price_ranges": {
"range": {
"field": "price",
"ranges": [
{ "to": 100 },
{ "from": 100, "to": 200 },
{ "from": 200 }
]
}
}
}
}
🔹 date_histogram(按时间分桶)
用途:按时间分组(如天、小时)
{
"aggs": {
"by_day": {
"date_histogram": {
"field": "timestamp",
"calendar_interval": "day"
}
}
}
}
2️⃣ Metric 聚合:数值计算
🔹 avg(平均值)
{
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
🔹 sum(求和)、max、min、count(文档数默认统计)
{
"aggs": {
"sum_price": {
"sum": { "field": "price" }
},
"max_price": {
"max": { "field": "price" }
}
}
}
3️⃣ 嵌套聚合:桶中嵌套度量 or 桶中嵌套桶
按 tag 分组后,再计算每组价格平均值:
{
"aggs": {
"group_by_tag": {
"terms": { "field": "tag.keyword" },
"aggs": {
"avg_price": {
"avg": { "field": "price" }
}
}
}
}
}
4️⃣ Pipeline 聚合(进阶)
例如统计每个 tag 的平均值,再算它们的平均值:
{
"aggs": {
"group_by_tag": {
"terms": { "field": "tag.keyword" },
"aggs": {
"avg_price": {
"avg": { "field": "price" }
}
}
},
"avg_of_avg": {
"avg_bucket": {
"buckets_path": "group_by_tag>avg_price"
}
}
}
}
返回结果结构说明
聚合的返回结果长这样:
{
"aggregations": {
"group_by_tag": {
"buckets": [
{
"key": "tag1",
"doc_count": 10,
"avg_price": {
"value": 99.5
}
},
...
]
}
}
}
实战小技巧
需求 | 方案 |
---|---|
查询结果 + 聚合 | 用 size: 0 只返回聚合结果 |
排序后 top N 分组 | terms + order + size |
聚合条件过滤 | 使用 filter 聚合 |
示例:综合案例
统计每个产品分类的销量总和,筛选价格大于 100 的商品:
{
"query": {
"range": {
"price": { "gt": 100 }
}
},
"aggs": {
"by_category": {
"terms": {
"field": "category.keyword",
"size": 10
},
"aggs": {
"total_sales": {
"sum": {
"field": "sales"
}
}
}
}
},
"size": 0
}