思路不清晰的小伙伴可以先在es中把聚合代码写出来
{ "aggs": { "brandAgg": { "terms": { "field": "brandName.keyword" }, "aggs": { "typeAgg": { "terms": { "field": "typeTwoName.keyword" } }, "ruleAgg": { "terms": { "field": "ruleName.keyword" }, "aggs": { "ruleValueAgg": { "terms": { "field": "ruleAttrValue.keyword" } } } } } } }
注:字段名称加keyword是精准查询,模糊查询可以去掉
查询完成后这是聚合的结构
在java代码中先把要聚合的名称创建出来
根据刚刚的es代码设置java中的terms名称和field后面的名称相对应
//构建聚合名称 TermsAggregationBuilder brandAgg = AggregationBuilders.terms("brandAgg").field("brandName.keyword"); TermsAggregationBuilder typeAgg = AggregationBuilders.terms("typeAgg").field("typeTwoName.keyword"); TermsAggregationBuilder ruleAgg = AggregationBuilders.terms("ruleAgg").field("ruleName.keyword"); TermsAggregationBuilder ruleValueAgg = AggregationBuilders.terms("ruleValueAgg").field("ruleAttrValue.keyword");
这里是根据es代码中创建的层级关系来依次分配
//根据聚合分配层级 brandAgg.subAggregation(typeAgg); brandAgg.subAggregation(ruleAgg); ruleAgg.subAggregation(ruleValueAgg); //添加最外层聚合 searchSourceBuilder.aggregation(brandAgg);
创建实体类来接参
/*=====================聚合分析=====================*/ /** * 查询到的所有商品所涉及的所有品牌 */ private Set<BrandVO> brands = new HashSet<>(); /** * 查询到的所有商品所涉及的所有分类 */ private Set<TypeVO> types = new HashSet<>(); /** * 查询到的所有商品所涉及的所有属性(规格) */ private Set<AttrVO> attrs = new HashSet<>(); @Data public static class BrandVO { private Long brandId; private String brandName; private String brandImg; } @Data public static class TypeVO { private Long TypeId; private String TypeName; } @Data public static class AttrVO { private Long attrId; private String attrName; private List<String> attrValue; } @Data public static class BreadCrumbsVO { private String attrName; private String attrValue; private String link; }
在方法中把参数先备好
//定义参数 Set<SearchResult.BrandVO> brandVOList = new HashSet<>(); Set<SearchResult.TypeVO> typeList = new HashSet<>(); Set<SearchResult.AttrVO> attrList = new HashSet<>();
首先获取最外层的参数
有一点需要更改的 回调参数是Aggregations需要改成Terms才能调取方法
//获取聚合参数 Aggregations brandAggregations = response.getAggregations(); //获取品牌 Terms brandGations = brandAggregations.get("brandAgg");
循环获取参数添加到指定的集合当中,这个获取的就相当于是es当中key的值
for (Terms.Bucket bucket : brandGations.getBuckets()) { //添加品牌 SearchResult.BrandVO brandVO = new SearchResult.BrandVO(); brandVO.setBrandName(bucket.getKeyAsString()); brandVOList.add(brandVO); }
最后在添加到实体类的对象当中
//添加对象中数据 result.getProductInfoList().addAll(productInfoList); result.getBrands().addAll(brandVOList); result.getAttrs().addAll(attrList); result.getTypes().addAll(typeList);
最后查询,就获取到了我们聚合后的值了,在根据业务进行下一步的操作
最后展示一下所有的代码
SearchResult result = new SearchResult(); try { //构建对象 SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); //构建聚合名称 TermsAggregationBuilder brandAgg = AggregationBuilders.terms("brandAgg").field("brandName.keyword"); TermsAggregationBuilder typeAgg = AggregationBuilders.terms("typeAgg").field("typeTwoName.keyword"); TermsAggregationBuilder ruleAgg = AggregationBuilders.terms("ruleAgg").field("ruleName.keyword"); TermsAggregationBuilder ruleValueAgg = AggregationBuilders.terms("ruleValueAgg").field("ruleAttrValue.keyword"); //根据聚合分配层级 brandAgg.subAggregation(typeAgg); brandAgg.subAggregation(ruleAgg); ruleAgg.subAggregation(ruleValueAgg); //添加最外层聚合 searchSourceBuilder.aggregation(brandAgg); //定义参数 Set<SearchResult.BrandVO> brandVOList = new HashSet<>(); Set<SearchResult.TypeVO> typeList = new HashSet<>(); Set<SearchResult.AttrVO> attrList = new HashSet<>(); //获取聚合参数 Aggregations brandAggregations = response.getAggregations(); //获取品牌 Terms brandGations = brandAggregations.get("brandAgg"); for (Terms.Bucket bucket : brandGations.getBuckets()) { //添加品牌 SearchResult.BrandVO brandVO = new SearchResult.BrandVO(); brandVO.setBrandName(bucket.getKeyAsString()); brandVOList.add(brandVO); //获取类型 Aggregations aggregations = bucket.getAggregations(); Terms typeGations = aggregations.get("typeAgg"); //添加类型 for (Terms.Bucket typeGationsBucket : typeGations.getBuckets()) { SearchResult.TypeVO typeVO = new SearchResult.TypeVO(); typeVO.setTypeName(typeGationsBucket.getKeyAsString()); typeList.add(typeVO); } //获取spu Terms ruleGations = aggregations.get("ruleAgg"); //添加spu for (Terms.Bucket ruleGationsBucket : ruleGations.getBuckets()) { SearchResult.AttrVO attrVO = new SearchResult.AttrVO(); attrVO.setAttrName(ruleGationsBucket.getKeyAsString()); //获取sku Aggregations attrValueAggregations = ruleGationsBucket.getAggregations(); Terms ruleValueGations = attrValueAggregations.get("ruleValueAgg"); //添加sku for (Terms.Bucket ruleValueGationsBucket : ruleValueGations.getBuckets()) { ArrayList<String> attrValueList = new ArrayList<>(); for (String attrValue : ruleValueGationsBucket.getKeyAsString().split(",")) { attrValueList.add(attrValue); } attrVO.setAttrValue(attrValueList); } attrList.add(attrVO); } } //添加对象中数据 result.getProductInfoList().addAll(productInfoList); result.getBrands().addAll(brandVOList); result.getAttrs().addAll(attrList); result.getTypes().addAll(typeList); } }catch (Exception ex){ log.error("检索ES失败: {}", ex); }
总结
原文地址:https://blog.csdn.net/qq_34160849/article/details/128120124