1.准备工作,先要在EsConstant类中添加一个常量值:
public static final Integer PRODUCT_PAGESIZE = 5;//分页的页数
1.1在SearchParam更改以下值
/**
* 是否显示有货 0(无库存) 1(有库存)
*/
private Integer hasStock=1;
/**
* 页码
*/
private Integer pageNum = 1;
2.在MallSearchServiceImpl写业务逻辑:
@Service
public class MallSearchServiceImpl implements MallSearchService {
@Autowired
private RestHighLevelClient client;
@Override
public SearchResult search(SearchParam searchParam) {
//构建请求的DEL检索数据
SearchRequest searchRequest = buildSearchRequest(searchParam);
SearchResponse searchResponse = null;
try {
client.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);
} catch (IOException e) {
e.printStackTrace();
}
SearchResult searchResult = buildSearchResult(searchResponse,searchParam);
return searchResult;
}
/**
* 构建请求的DEL检索数据
*
* @param searchParam
* @return
*/
private SearchRequest buildSearchRequest(SearchParam searchParam) {
//DEL的构建器
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
/**
* 过滤(按照属性、分类、品牌、价格区间、库存)
*/
//1、构建bool-query
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//1.1 must-模糊匹配
if (!StringUtils.isEmpty(searchParam.getKeyword())) {
boolQuery.must(QueryBuilders.matchQuery("skuTitle", searchParam.getKeyword()));
}
//1.2.1 filter-按照三级分类id查询
if (searchParam.getCatalog3Id() != null) {
boolQuery.filter(QueryBuilders.termQuery("catalogId", searchParam.getCatalog3Id()));
}
//1.2.2 filter-按照品牌id查询
if (searchParam.getBrandId() != null && searchParam.getBrandId().size() > 0) {
boolQuery.filter(QueryBuilders.termsQuery("brandId", searchParam.getBrandId()));
}
//1.2.3 filter-按照是否有库存进行查询
if (searchParam.getHasStock() != null) {
boolQuery.filter(QueryBuilders.termsQuery("hasStock", searchParam.getHasStock() == 1));
}
//1.2.4 filter-按照区间进行查询 1_500/_500/500_
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("skuPrice");
if (!StringUtils.isEmpty(searchParam.getSkuPrice())) {
String[] prices = searchParam.getSkuPrice().split("_");
if (prices.length == 1) {
if (searchParam.getSkuPrice().startsWith("_")){
rangeQuery.lte(prices[0]);
}
if (searchParam.getSkuPrice().endsWith("_")){
rangeQuery.gte(prices[0]);
}
} else if (prices.length == 2) {
rangeQuery.gte(prices[0]).lte(prices[1]);
}
}
//1.2.5 filter-按照属性进行查询
List<String> attrs = searchParam.getAttrs();
if (attrs!=null&&attrs.size()>0) {
//attrs=1_5寸:8寸&2_16G:8G
attrs.forEach(attr->{
BoolQueryBuilder nestedBoolQuery = QueryBuilders.boolQuery();
String[] s = attr.split("_");
String attrId = s[0];//检索属性的ID
String[] attrValues = s[1].split(":");//检索属性的值
nestedBoolQuery.must(QueryBuilders.termQuery("attrs.attrId", attrId))
.must(QueryBuilders.termsQuery("attrs.attrValue",attrValues));
//每一个必须都生成一个nested查询
NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("attrs", nestedBoolQuery, ScoreMode.None);
boolQuery.filter(nestedQuery);
});
}
//把以前所有的条件都拿来进行封装
sourceBuilder.query(boolQuery);
/**
* 排序,分页,高亮,
*/
//2.1 排序 eg:sort=saleCount_desc/asc
if (!StringUtils.isEmpty(searchParam.getSort())){
String[] sortSplit = searchParam.getSort().split("_");
sourceBuilder.sort(sortSplit[0], sortSplit[1].equalsIgnoreCase("asc") ? SortOrder.ASC : SortOrder.DESC);
}
//2.2、分页
sourceBuilder.from((searchParam.getPageNum() - 1) * EsConstant.PRODUCT_PAGESIZE);
sourceBuilder.size(EsConstant.PRODUCT_PAGESIZE);
//2.3 高亮highlight
if(!StringUtils.isEmpty(searchParam.getKeyword())){
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("skuTitle");
highlightBuilder.preTags("<b style='color:red'>");
highlightBuilder.postTags("</b>");
sourceBuilder.highlighter(highlightBuilder);
}
String s = sourceBuilder.toString();
System.out.println("构建的DSL"+s);
SearchRequest request = new SearchRequest(new String[]{EsConstant.PRODUCT_INDEX}, sourceBuilder);
return request;
}
/**
* 返回结果数据
* @param searchResponse
* @param searchParam
* @return
*/
private SearchResult buildSearchResult(SearchResponse searchResponse, SearchParam searchParam) {
return null;
}
}