思路不清晰的小伙伴可以先在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