如何对Elasticsearch聚合结果进行自定义逻辑分组?
自定义分组Elasticsearch聚合结果
我有如下Elasticsearch聚合查询:
"aggs": { "minValue": { "min": { "field": "field1" } }, "maxValue": { "max": { "field": "field1" } }, "sumValue": { "sum": { "field": "field1" } }, "terms1": { "terms": { "field": "field3" } }, "terms2": { "terms": { "field": "field4" } } }
对应的返回结果如下:
"aggregations": { "minValue": { "value": 4 }, "maxValue": { "value": 100 }, "sumValue": { "value": 43342 }, "terms1": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "electronic", "doc_count": 6 } // ... 其他桶数据 ] }, "terms2": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "bmw", "doc_count": 4 } // ... 其他桶数据 ] } }
我需要将返回结果按自定义逻辑分组,分成value_aggr(值类型聚合,包含min、max、sum这类单值结果)和term_aggr(桶类型聚合,包含terms这类多桶结果)两组,方便聚合数量较多时查询,也让客户端能轻松区分聚合类型。
解决方案1:查询阶段直接嵌套分组(推荐)
直接修改聚合查询,把不同类型的聚合嵌套到对应的分组下,Elasticsearch会直接返回分组后的结果,无需客户端额外处理:
修改后的聚合查询
"aggs": { "value_aggr": { "aggs": { "minValue": { "min": { "field": "field1" } }, "maxValue": { "max": { "field": "field1" } }, "sumValue": { "sum": { "field": "field1" } } } }, "term_aggr": { "aggs": { "terms1": { "terms": { "field": "field3" } }, "terms2": { "terms": { "field": "field4" } } } } }
对应的返回结果结构
"aggregations": { "value_aggr": { "minValue": { "value": 4 }, "maxValue": { "value": 100 }, "sumValue": { "value": 43342 } }, "term_aggr": { "terms1": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "electronic", "doc_count": 6 } // ... 其他桶数据 ] }, "terms2": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "bmw", "doc_count": 4 } // ... 其他桶数据 ] } } }
解决方案2:客户端处理返回结果
如果无法修改原始查询,可以在客户端拿到聚合结果后,通过遍历字段判断类型来分组。以下是JavaScript示例:
// 假设原始聚合结果存储在aggregations变量中 const aggregations = { // ... 原始返回的聚合数据 }; const groupedResult = { value_aggr: {}, term_aggr: {} }; // 遍历聚合字段,按结构分组 Object.entries(aggregations).forEach(([key, value]) => { if ('value' in value) { // 包含value字段的归为值类型聚合 groupedResult.value_aggr[key] = value; } else if ('buckets' in value) { // 包含buckets字段的归为桶类型聚合 groupedResult.term_aggr[key] = value; } }); console.log(groupedResult);
运行后就能得到分组后的结构,和方案1的返回结果一致。
内容的提问来源于stack exchange,提问作者beatrice
相关产品推荐
相关产品推荐

