Elasticsearch桶聚合,目的就是数据分组,先将数据按指定的条件分成多个组,然后对每一个组进行统计。
不了解Elasticsearch桶聚合概念,可以先学习下Elasticsearch桶聚合教程
下面分别介绍golang elasticsearch桶聚合的写法
1.Terms聚合
package main
import (
"context"
"fmt"
"github.com/olivere/elastic/v7"
"log"
)
func main() {
// 创建ES client
client, err := elastic.NewClient()
if err != nil {
// Handle error
panic(err)
}
// 执行ES请求需要提供一个上下文对象
ctx := context.Background()
// 创建Terms桶聚合
aggs := elastic.NewTermsAggregation().
Field("shop_id") // 根据shop_id字段值,对数据进行分组
searchResult, err := client.Search().
Index("shops"). // 设置索引名
Query(elastic.NewMatchAllQuery()). // 设置查询条件
Aggregation("shop", aggs). // 设置聚合条件,并为聚合条件设置一个名字
Size(0). // 设置分页参数 - 每页大小,设置为0代表不返回搜索结果,仅返回聚合分析结果
Do(ctx) // 执行请求
if err != nil {
// Handle error
panic(err)
}
// 使用Terms函数和前面定义的聚合条件名称,查询结果
agg, found := searchResult.Aggregations.Terms("shop")
if !found {
log.Fatal("没有找到聚合数据")
}
// 遍历桶数据
for _, bucket := range agg.Buckets {
// 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
bucketValue := bucket.Key
// 打印结果, 默认桶聚合查询,都是统计文档总数
fmt.Printf("bucket = %q 文档总数 = %d\n", bucketValue, bucket.DocCount)
}
}
2.Histogram聚合
// 创建Histogram桶聚合
aggs := elastic.NewHistogramAggregation().
Field("price"). // 根据price字段值,对数据进行分组
Interval(50) // 分桶的间隔为50,意思就是price字段值按50间隔分组
searchResult, err := client.Search().
Index("order"). // 设置索引名
Query(elastic.NewMatchAllQuery()). // 设置查询条件
Aggregation("prices", aggs). // 设置聚合条件,并为聚合条件设置一个名字
Size(0). // 设置分页参数 - 每页大小,设置为0代表不返回搜索结果,仅返回聚合分析结果
Do(ctx) // 执行请求
if err != nil {
// Handle error
panic(err)
}
// 使用Histogram函数和前面定义的聚合条件名称,查询结果
agg, found := searchResult.Aggregations.Histogram("prices")
if !found {
log.Fatal("没有找到聚合数据")
}
// 遍历桶数据
for _, bucket := range agg.Buckets {
// 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
bucketValue := bucket.Key
// 打印结果, 默认桶聚合查询,都是统计文档总数
fmt.Printf("bucket = %q 文档总数 = %d\n", bucketValue, bucket.DocCount)
}
3.Date histogram聚合
// 创DateHistogram桶聚合
aggs := elastic.NewDateHistogramAggregation().
Field("date"). // 根据date字段值,对数据进行分组
// 分组间隔:month代表每月、支持minute(每分钟)、hour(每小时)、day(每天)、week(每周)、year(每年)
CalendarInterval("month").
// 设置返回结果中桶key的时间格式
Format("yyyy-MM-dd")
searchResult, err := client.Search().
Index("order"). // 设置索引名
Query(elastic.NewMatchAllQuery()). // 设置查询条件
Aggregation("sales_over_time", aggs). // 设置聚合条件,并为聚合条件设置一个名字
Size(0). // 设置分页参数 - 每页大小,设置为0代表不返回搜索结果,仅返回聚合分析结果
Do(ctx) // 执行请求
if err != nil {
// Handle error
panic(err)
}
// 使用DateHistogram函数和前面定义的聚合条件名称,查询结果
agg, found := searchResult.Aggregations.DateHistogram("sales_over_time")
if !found {
log.Fatal("没有找到聚合数据")
}
// 遍历桶数据
for _, bucket := range agg.Buckets {
// 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
bucketValue := bucket.Key
// 打印结果, 默认桶聚合查询,都是统计文档总数
fmt.Printf("bucket = %q 文档总数 = %d\n", bucketValue, bucket.DocCount)
}
4.Range聚合
// 创Range桶聚合
aggs := elastic.NewRangeAggregation().
Field("price"). // 根据price字段分桶
AddUnboundedFrom(100). // 范围配置, 0 - 100
AddRange(100.0, 200.0). // 范围配置, 100 - 200
AddUnboundedTo(200.0) // 范围配置,> 200的值
searchResult, err := client.Search().
Index("order"). // 设置索引名
Query(elastic.NewMatchAllQuery()). // 设置查询条件
Aggregation("price_ranges", aggs). // 设置聚合条件,并为聚合条件设置一个名字
Size(0). // 设置分页参数 - 每页大小,设置为0代表不返回搜索结果,仅返回聚合分析结果
Do(ctx) // 执行请求
if err != nil {
// Handle error
panic(err)
}
// 使用Range函数和前面定义的聚合条件名称,查询结果
agg, found := searchResult.Aggregations.Range("price_ranges")
if !found {
log.Fatal("没有找到聚合数据")
}
// 遍历桶数据
for _, bucket := range agg.Buckets {
// 每一个桶都有一个key值,其实就是分组的值,可以理解为SQL的group by值
bucketValue := bucket.Key
// 打印结果, 默认桶聚合查询,都是统计文档总数
fmt.Printf("bucket = %q 文档总数 = %d\n", bucketValue, bucket.DocCount)
}
5.嵌套聚合的用法
任意聚合类型都支持嵌套,桶聚合可以嵌套桶聚合,也可以嵌套指标聚合。
例子:
// 创terms桶聚合
aggs := elastic.NewTermsAggregation().Field("shop_id")
// 创建Sum指标聚合
sumAggs := elastic.NewSumAggregation().Field("price")
// terms聚合嵌套指标聚合
aggs.SubAggregation("total_price", sumAggs)
提示:golang elasticsearch的用法,本质上还是对elasticsearch接口的封装,所以用法跟elasticsearch的语法完全一致。