Elasticsearch如何对object字段做sum聚合统计各经销商价格总和
问题根源
Elasticsearch 默认对object类型的数组采用扁平化存储逻辑,你写入的第一条文档存储后会被处理为如下结构:
{ "name": "LED TV", "resellers.reseller": ["companyA", "companyB"], "resellers.price": [350, 500] }
同一数组元素下的reseller和price绑定关系会完全丢失,直接对普通object类型做聚合会出现跨对象的错误匹配,永远无法得到你预期的统计结果。你需要先将resellers字段定义为nested(嵌套)类型,保留数组内每个对象的独立关联关系,再通过嵌套聚合完成统计。
实现步骤
1. 定义正确的索引Mapping
如果是新建索引,直接指定resellers为nested类型:
PUT records { "mappings": { "properties": { "name": { "type": "keyword" }, "resellers": { "type": "nested", "properties": { "reseller": { "type": "keyword" }, "price": { "type": "integer" } } } } } }
如果索引中已有存量数据,需要先创建符合上述Mapping的新索引,再通过_reindex接口将旧索引数据迁移到新索引后再执行查询。
2. 写入测试数据
按照你提供的格式写入两条测试文档即可。
3. 执行嵌套聚合查询
调用_search接口时使用nested聚合,先进入嵌套字段路径,再按经销商分组、对价格求和:
GET records/_search { "size": 0, "aggs": { "reseller_agg": { "nested": { "path": "resellers" }, "aggs": { "group_by_reseller_name": { "terms": { "field": "resellers.reseller" }, "aggs": { "reseller_total_sales": { "sum": { "field": "resellers.price" } } } } } } } }
返回结果
查询返回的聚合段和你的预期完全一致:
- companyA 总价为700(两条文档中各350累加)
- companyB 总价为500
- companyC 总价为500
核心返回片段参考:
{ "aggregations": { "reseller_agg": { "doc_count": 4, "group_by_reseller_name": { "buckets": [ { "key": "companyA", "doc_count": 2, "reseller_total_sales": { "value": 700 } }, { "key": "companyB", "doc_count": 1, "reseller_total_sales": { "value": 500 } }, { "key": "companyC", "doc_count": 1, "reseller_total_sales": { "value": 500 } } ] } } } }
内容的提问来源于stack exchange,提问作者seongpar
相关产品推荐
相关产品推荐

