Elasticsearch按字段分组聚合求和实现技术咨询
Elasticsearch 按 Category 聚合求和 Price 的实现方案
嘿,我来帮你搞定这个按分类求和价格的需求!你已经找对方向了——确实要用**聚合(Aggregation)**来实现,具体来说就是先按 category 字段做分组聚合,再对每个分组里的 price 字段做求和聚合。
下面是完整的代码实现,基于你已经开始写的 SearchRequest 来补全:
import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.search.aggregations.AggregationBuilders; import org.elasticsearch.search.aggregations.bucket.terms.Terms; import org.elasticsearch.search.aggregations.metrics.sum.Sum; import org.elasticsearch.search.builder.SearchSourceBuilder; import java.io.IOException; public class AggregationExample { public static void main(String[] args) throws IOException { // 假设你已经初始化了 RestHighLevelClient 实例 RestHighLevelClient client = new RestHighLevelClient(...); SearchRequest searchRequest = new SearchRequest("products"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); // 1. 按 category 字段做分组聚合,命名为 "category_group" Terms.TermsAggregationBuilder categoryAgg = AggregationBuilders.terms("category_group") .field("category.keyword"); // 注意这里要用 keyword 类型,避免分词影响分组 // 2. 在每个分组内对 price 字段求和,命名为 "total_price" categoryAgg.subAggregation(AggregationBuilders.sum("total_price") .field("price")); // 将聚合配置添加到查询源构建器 searchSourceBuilder.aggregation(categoryAgg); // 如果只需要聚合结果不需要原始文档,可以关闭返回文档 searchSourceBuilder.size(0); searchRequest.source(searchSourceBuilder); // 执行查询 SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); // 解析聚合结果 Terms categoryTerms = response.getAggregations().get("category_group"); for (Terms.Bucket bucket : categoryTerms.getBuckets()) { String category = bucket.getKeyAsString(); Sum totalPrice = bucket.getAggregations().get("total_price"); double sum = totalPrice.getValue(); System.out.println(category + " - " + sum); } // 记得关闭客户端 client.close(); } }
关键代码解释:
TermsAggregationBuilder:用来按category字段做分组,这里一定要用category.keyword而不是直接用category——因为如果你的category字段是 text 类型的话,会被分词,用 keyword 子字段才能保证分组的准确性(比如不会把 "fruit" 拆成单个字符分组)。SumAggregationBuilder:作为子聚合添加到分组聚合里,负责计算每个分组内price字段的总和。searchSourceBuilder.size(0):这个很实用,因为我们只需要聚合结果,不需要返回原始的文档数据,设置size(0)可以减少数据传输量,提升性能。
运行这段代码后,你就能得到想要的输出:
fruit - 4.4 vegs - 0.95
内容的提问来源于stack exchange,提问作者Igor
相关产品推荐
相关产品推荐

