es——java实现基本搜索功能
在输入框输入搜索关键字、点击页面过滤项、翻页、排序都会导致请求发出,查询商品信息:
需要实现的功能包括:
-
关键字搜索
-
分类、品牌、价格过滤
-
排序
-
分页
-
高亮
-
竞价排名
接口说明:
controller层:
/**
* 关键字搜索,分页
*/
@PostMapping("/list")
public PageDTO<ItemDoc> list(@RequestBody RequestParams params){
log.info("关键字搜索,分页===前后端联通==" + params);
this.isearchService.list(params);
return this.isearchService.list(params);
}
service层:
/**
* 搜索关键字,分页
*/
PageDTO<ItemDoc> list(RequestParams params);
service实现类:
@Autowired
private RestHighLevelClient client;
/**
* 搜索关键字,分页
*/
@Override
public PageDTO<ItemDoc> list(RequestParams params) {
try {
//准备Request
SearchRequest request = new SearchRequest("item");
//设置请求参数
buildBasicQuery(params, request);
//排序 sort
if (!StringUtils.isBlank(params.getSortBy())) {
if ("sold".equals(params.getSortBy())) {//按评价排序
request.source().sort(params.getSortBy(), SortOrder.DESC);
}
if ("price".equals(params.getSortBy())) {//按价格排序
request.source().sort(params.getSortBy(), SortOrder.ASC);
}
}
//分页
request.source().from(params.getPage() - 1).size(params.getSize());
//高亮
request.source().highlighter(
new HighlightBuilder().field("name").requireFieldMatch(false)
);
//执行请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
//解析结果
PageDTO<ItemDoc> pageDTO = this.processResponse(response);
return pageDTO;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 解析响应结果
*
* @param response
*/
private PageDTO<ItemDoc> processResponse(SearchResponse response) {
PageDTO<ItemDoc> pageDTO = new PageDTO<>();
//酒店数据集合
List<ItemDoc> list = new ArrayList<ItemDoc>();
//解析结果
SearchHits searchHits = response.getHits();
//获取文档总数量
TotalHits total = searchHits.getTotalHits();
pageDTO.setTotal(total.value);
//获取文档详情
SearchHit[] hits = searchHits.getHits();
for (SearchHit hit : searchHits) {
//文档内容
String json = hit.getSourceAsString();
//将json格式转为对象
ItemDoc itemDoc = JSONObject.parseObject(json, ItemDoc.class);
//高亮
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if (!CollectionUtils.isEmpty(highlightFields)) {
HighlightField highlightField = highlightFields.get("name");
//高亮处理后的名称
String highLightName = highlightField.getFragments()[0].string();
//覆盖之前的名称
itemDoc.setName(highLightName);
}
//将对先加入集合
list.add(itemDoc);
}
pageDTO.setList(list);
return pageDTO;
}
/**
* 查询条件
*
* @param params
* @param request
*/
private void buildBasicQuery(RequestParams params, SearchRequest request) {
// 1.构建BooleanQuery
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
// 2.关键字搜索
if (!StringUtils.isBlank(params.getKey())) {
boolQuery.must(QueryBuilders.matchQuery("all", params.getKey()));
} else {
boolQuery.must(QueryBuilders.matchAllQuery());
}
//过滤
//品牌
if (!StringUtils.isBlank(params.getBrand())) {
boolQuery.filter(QueryBuilders.termQuery("brand", params.getBrand()));
}
//分类
if (!StringUtils.isBlank(params.getCategory())) {
boolQuery.filter(QueryBuilders.termQuery("category", params.getCategory()));
}
//价格
if (params.getMinPrice() != null && params.getMaxPrice() != null) {
boolQuery.filter(QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));
}
//复合查询——算分函数查询
FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(
boolQuery, //原始查询
new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
new FunctionScoreQueryBuilder.FilterFunctionBuilder(
QueryBuilders.termQuery("isAD", true), //过滤条件(符合条件的文档,重新打分)
ScoreFunctionBuilders.weightFactorFunction(10) //如何打分
)
}
).boostMode(CombineFunction.SUM);//加权规则(新旧得分运算规则)
//设置整体查询
request.source().query(functionScoreQueryBuilder);
}