Elasticsearch按name分组:仅累加status为won的value值实现方案
解决Elasticsearch分组后仅对指定status记录求和的问题
你现在的问题是聚合时没过滤掉status != 'won'的记录,导致总和包含了lost的数值。这里有两种简单可行的解决方式,都能得到你想要的结果:
方案一:先过滤再求和(推荐,性能更优)
这种方式会先在每个name分组里筛选出status='won'的文档,再对这些文档的value求和,避免了对无关数据的计算,性能表现更好。
aggs: { by_name: { terms: { field: 'name' }, aggs: { total_value: { filter: { term: { status: 'won' } }, aggs: { sum_won_values: { sum: { field: 'value' } } } } } } }
返回结果里,每个name分组下的sum_won_values就是你需要的total_value,对应Foo是22、Bar是4,完全符合预期。
方案二:使用脚本在求和时判断条件
如果需要更灵活的条件判断(比如同时匹配多个status值),可以用脚本直接在求和阶段做筛选:
aggs: { by_name: { terms: { field: 'name' }, aggs: { total_value: { sum: { script: { source: "doc['status'].value == 'won' ? doc['value'].value : 0" } } } } } }
这个脚本逻辑很直观:如果当前文档的status是'won',就取它的value值参与求和;否则用0代替,最终的总和自然只会包含符合条件的记录。
两种方案都能满足需求,优先推荐方案一,尤其是数据量较大时,提前过滤能显著提升聚合效率。
内容的提问来源于stack exchange,提问作者cyberwombat
相关产品推荐
相关产品推荐

