Elasticsearch聚合出商品的一级分类与二级分类组装成树型结构返回

项目中要对es中的商品聚合出 前端一级分类与二级分类,并且对一二级分类按设置的排序值进行排序后返回树型结构;

项目中一个商品可以对应多个前台分类 , 所以es索引中前台分类用Nested类型存储,_mapping结构如下:

 

 

 存储数据时对 一二三级分类数据的相关字段拼接成 id|name|parentId|sort|level|icon  这样的字符串;

 

 java代码如下:

代码中:EsProductFields.frontFirstCategoryInfo="frontCategoryList.frontFirstCategoryInfo.keyword"

              EsProductFields.frontSecondCategoryInfo="frontCategoryList.frontSecondCategoryInfo.keyword"

 

       @Autowired
private ElasticsearchRestTemplate es;

 


public List<ESCategoryDTO> selectCategoryList(SearchParameter param) {
if (param.getBuyerDistrictId() == null && Objects.nonNull(param.getBuyerId())) {
if (ObjectUtil.equal(param.getRequestSource(), SearchRequestSourceEnum.JDE_CHANNEL_PURCHASE.getCode())) {
param.setBuyerDistrictId(null);
} else {
Long buyerDistrictId = remoteSellerClient.getBuyerAreaId(param.getBuyerId()).getData();
param.setBuyerDistrictId(buyerDistrictId);
}
}
NativeSearchQueryBuilder queryBuilder = getSearchQuery(param);
//聚合一级分类
TermsAggregationBuilder firstTermsAgg = AggregationBuilders.terms("firstAgg").field(EsProductFields.frontFirstCategoryInfo);
firstTermsAgg.size(200);
FilterAggregationBuilder filterAgg1 = new FilterAggregationBuilder("filterAgg", getFilter(param));
filterAgg1.subAggregation(firstTermsAgg);
//聚合二级分类
TermsAggregationBuilder secondTermsAgg = AggregationBuilders.terms("secondAgg").field(EsProductFields.frontSecondCategoryInfo);
secondTermsAgg.size(10000);
filterAgg1.subAggregation(secondTermsAgg);
queryBuilder.addAggregation(filterAgg1);
List<String> list = new ArrayList<>();
SearchHits<EsProductDTO> search = es.search(queryBuilder.build(), EsProductDTO.class);
if (search.hasSearchHits()) {
for (Aggregation item : search.getAggregations()) {
JSONObject jsonObject = JSONUtil.parseObj(item);
JSONArray subAggregations = jsonObject.getJSONArray("aggregations");
for (Object subAggregation : subAggregations) {
JSONObject subAggJsonObject = JSONUtil.parseObj(subAggregation);
JSONArray buckets = subAggJsonObject.getJSONArray("buckets");
for (Object bucket : buckets) {
JSONObject model = JSONUtil.parseObj(bucket);
list.add(model.get("key").toString());
}
}
}
}
List<ESCategoryDTO> categoryList = new ArrayList<>();
if (CollUtil.isNotEmpty(list)) {
for (String item : list) {
//id|name|parentId|sort|level|icon 分类信息按竖线分割
String[] categoryArr = item.split("\\|");
ESCategoryDTO model = new ESCategoryDTO();
model.setId(categoryArr[0]);
model.setName(categoryArr[1]);
model.setParentId(Long.parseLong(categoryArr[2]));
model.setSort(Integer.parseInt(categoryArr[3]));
model.setLevel(Integer.parseInt(categoryArr[4]));
model.setIcon(categoryArr[5].equals("null") ? "" : categoryArr[5]);
model.setCategoryType(CategoryTypeEnum.CATEGORY.getCode());
categoryList.add(model);
}
}
if (CollUtil.isNotEmpty(categoryList)) {
//组装成树型结构
List<ESCategoryDTO> firstCategoryList = categoryList.stream().filter(c -> c.getLevel().equals(CategoryLevel.FIRST)).collect(Collectors.toList());
//一级分类按sort排序
firstCategoryList.sort(Comparator.comparing(ESCategoryDTO::getSort).reversed());
for (ESCategoryDTO item : firstCategoryList) {
List<ESCategoryDTO> secondCategoryList = categoryList.stream().filter(c -> c.getParentId().equals(Long.parseLong(item.getId()))).collect(Collectors.toList());
//二级分类按sort排序
secondCategoryList.sort(Comparator.comparing(ESCategoryDTO::getSort).reversed());
item.setChildCategoryList(secondCategoryList);
}
return firstCategoryList;
}
return new ArrayList<>();
}
 

 

posted @ 2022-06-23 16:27  清玄-2012  阅读(479)  评论(0编辑  收藏  举报