有一个数据聚合的需求,es中存有10W条以上的数据,需要对这批数据做聚合查询。 为了处理这个问题,有几种方法可以考虑:
1.增加size参数,
增加terms聚合中size参数的值可以让你获取更多的桶。但是,请注意,将这个值设置得过高可能会对Elasticsearch集群的性能造成影响。
2.使用composite聚合进行分页
如果你需要处理的唯一值数量远远超过了10000,或者你希望以一种可扩展的方式处理大量的唯一值,可以使用composite聚合来进行分页处理。composite聚合允许你基于多个字段进行聚合,并且可以通过after参数来获取更多的数据,实现分页。
3.考虑调整search.max_buckets设置
在某些情况下,你可能会遇到由于聚合操作产生的总桶数超过Elasticsearch限制(默认是10000个桶)而导致的问题。这个限制可以通过更改集群设置search.max_buckets来调整。但是,请谨慎使用这个方法,因为大量的桶可能会对集
在以上方案中由于方案1和方案3都会对Elasticsearch集群的性能造成影响,最终选用方案2.
以下为golang实现代码
package main
import (
"context"
"fmt"
"log"
"github.com/olivere/elastic/v7"
)
func main() {
client, err := elastic.NewClient()
if err != nil {
log.Fatalf("Error creating the client: %s", err)
}
ctx := context.Background()
indexName := "your_index_name" // 替换为你的索引名
var afterKey map[string]interface{} = nil
for {
// 构建composite aggregation,并在存在afterKey时使用它
compositeAgg := elastic.NewCompositeAggregation().
Size(10000).
Sources(
elastic.NewCompositeAggregationTermsValuesSource("your_field_name").Field("your_field_name"),
).
SubAggregation("sum_field", elastic.NewSumAggregation().Field("your_sum_field_name"))
if afterKey != nil {
compositeAgg = compositeAgg.After(afterKey)
}
// 执行查询
searchResult, err := client.Search().
Index(indexName).
Query(elastic.NewMatchAllQuery()).
Aggregation("composite_agg", compositeAgg).
Do(ctx)
if err != nil {
log.Fatalf("Error getting response: %s", err)
}
// 解析聚合结果
agg, found := searchResult.Aggregations.Composite("composite_agg")
if !found {
log.Fatal("Expected to find the 'composite_agg' aggregation, but did not.")
}
for _, bucket := range agg.Buckets {
yourFieldName, _ := bucket.Key["your_field_name"].(string)
sumField, found := bucket.Aggregations.
if !found {
log.Fatal("Expected to find the 'sum_field' sub-aggregation, but did not.")
}
fmt.Printf("yourFieldName: %s, sum_field: %f\n", yourFieldName, *sumField.Value)
}
// 如果after_key不存在,则退出循环
if agg.AfterKey == nil {
break
}
// 为下一次查询准备afterKey
afterKey = agg.AfterKey
}
}
这个例子展示了如何构造一个查询,使用composite聚合按照一个字段进行分组,并对另一个字段求和。你可以根据需要调整size参数来控制每次请求返回的聚合桶的数量,以及通过after参数实现分页,不断获取下一批数据,直到获取完所有分组的数据。