此博客用于个人学习,来源于网上,对知识点进行一个整理。
1. 生成分类和品牌过滤:
1.1 过滤结果分析:
首先看下页面要实现的效果:
整个过滤部分有3块:
- 顶部的导航,已经选择的过滤条件展示:
- 商品分类面包屑,根据用户选择的商品分类变化
- 其它已选择过滤参数
- 过滤条件展示,又包含3部分:
- 商品分类展示
- 品牌展示
- 其它规格参数
- 展开或收起的过滤条件的按钮
顶部导航要展示的内容跟用户选择的过滤条件有关。
- 比如用户选择了某个商品分类,则面包屑中才会展示具体的分类
- 比如用户选择了某个品牌,列表中才会有品牌信息。
所以,这部分需要依赖第二部分:过滤条件的展示和选择。
展开或收起的按钮是否显示,取决于过滤条件有多少,如果很少,那么就没必要展示。所以也是跟第二部分的过滤条件有关。
这样分析来看,我们必须先做第二部分:过滤条件展示。
1.2 扩展返回的结果:
用户搜索的条件会对商品进行过滤,而在搜索结果中,不一定包含所有的分类和品牌,直接展示出所有商品分类,让用户选择显然是不合适的。无论是分类信息,还是品牌信息,都应该从搜索的结果商品中进行聚合得到。
原来,我们返回的结果是 PageResult 对象,里面只有 total、totalPage、items 3个属性。但是现在要对商品分类和品牌进行聚合,数据显然不够用,我们需要对返回的结果进行扩展,添加分类和品牌的数据。
分类:页面显示了分类名称,但背后肯定要保存id信息。所以至少要有 id 和 name
品牌:页面展示的有 logo,有文字,当然肯定有id,基本上是品牌的完整数据
我们新建一个类,继承 PageResult,然后扩展两个新的属性:分类集合和品牌集合:
public class SearchResult extends PageResult<Goods> {
private List<Map<String, Object>> categories;
private List<Brand> brands;
public SearchResult() {
}
public SearchResult(List<Map<String, Object>> categories, List<Brand> brands) {
this.categories = categories;
this.brands = brands;
}
public SearchResult(List<Goods> items, Long total, List<Map<String, Object>> categories, List<Brand> brands) {
super(items, total);
this.categories = categories;
this.brands = brands;
}
public SearchResult(List<Goods> items, Long total, Integer totalPage, List<Map<String, Object>> categories, List<Brand> brands) {
super(items, total, totalPage);
this.categories = categories;
this.brands = brands;
}
public List<Map<String, Object>> getCategories() {
return categories;
}
public void setCategories(List<Map<String, Object>> categories) {
this.categories = categories;
}
public List<Brand> getBrands() {
return brands;
}
public void setBrands(List<Brand> brands) {
this.brands = brands;
}
}
1.3 聚合商品分类和品牌:
我们修改搜索的业务逻辑,对分类和品牌聚合。
因为索引库中只有 id,所以我们根据 id 聚合,然后再根据 id 去查询完整数据。
所以,商品微服务需要提供一个接口:根据品牌 id 集合,批量查询品牌。
public SearchResult search(SearchRequest searchRequest) {
if (StringUtils.isBlank(searchRequest.getKey())){
return null;
}
//自定义查询构建器
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
//添加查询条件
// 这里用到and是因为我们查询一项东西的时候基本上都是获取交集,例如:小米手机,是小米加上手机,而不是查到包含小米和手机的字段商品就行了
//QueryBuilder basicQuery = QueryBuilders.matchQuery("all", searchRequest.getKey()).operator(Operator.AND);
BoolQueryBuilder basicQuery = buildBoolQueryBuilder(searchRequest);
queryBuilder.withQuery(basicQuery);
//添加分页,分页页码从0开始
queryBuilder.withPageable(PageRequest.of(searchRequest.getPage()-1,searchRequest.getSize()));
//添加结果过滤
queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]