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) {
NativeSearchQueryBuilder queryBuilder = getSearchQuery(param);
queryBuilder.withFilter(queryMustFilter(getFilter(param)));
queryBuilder.withPageable(PageRequest.of(0, 1));
//聚合一级分类
TermsAggregationBuilder firstTermsAgg = AggregationBuilders.terms(EsProductFields.frontFirstCategoryInfo).field(EsProductFields.frontFirstCategoryInfo);
firstTermsAgg.size(200);
queryBuilder.addAggregation(firstTermsAgg);
//聚合二级分类
TermsAggregationBuilder secondTermsAgg = AggregationBuilders.terms(EsProductFields.frontSecondCategoryInfo).field(EsProductFields.frontSecondCategoryInfo);
secondTermsAgg.size(10000);
queryBuilder.addAggregation(secondTermsAgg);
List<ESCategoryDTO> categoryList = new ArrayList<>();
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 buckets = jsonObject.getJSONArray("buckets");
for (Object bucket : buckets) {
JSONObject model = JSONUtil.parseObj(bucket);
list.add(model.get("key").toString());
}
}
}
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]);
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<>();
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章