目录
一、实现输入搜索功能
1、下载代码,在idea上打开
2、新建RequestParams类,用于接收解析请求
java
@Data
public class RequestParams {
private String key;
private Integer page;
private Integer size;
private String sortBy;
}
3、在启动类中加入客户端地址Bean,以便实现服务
java
@Bean
public RestHighLevelClient client(){
return new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.248.152:9200")
));
}
4、编写搜索方法
java
PageResult search(RequestParams params);
5、新建返回分页结果类
java
@Data
public class PageResult {
private long total;
private List<HotelDoc> hotels;
public PageResult() {
}
public PageResult(long total, List<HotelDoc> hotels) {
this.total = total;
this.hotels = hotels;
}
}
6、实现搜索方法
java
@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {
@Autowired
private RestHighLevelClient client;
@Override
public PageResult search(RequestParams params) {
// 准备Request对象
try {
SearchRequest request = new SearchRequest("hotel");
String key = params.getKey();
// 准备DSL
if (key==null || "".equals(key)){
request.source().query(QueryBuilders.matchAllQuery());
}else {
request.source().query(QueryBuilders.matchQuery("name", key));
}
// 分页
Integer page = params.getPage();
Integer size = params.getSize();
request.source().from((page-1)*size).size(size);
// 发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return extracted(response);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private PageResult extracted(SearchResponse response) {
// 解析响应
SearchHits searchHits = response.getHits();
// 获取总条数
long value = searchHits.getTotalHits().value;
System.out.println("共搜索到" + value + "条数据!");
// 获取文档数组
SearchHit[] hits = searchHits.getHits();
ArrayList<HotelDoc> list = new ArrayList<>();
// 遍历
for (SearchHit hit : hits) {
// 获取文档source
String json = hit.getSourceAsString();
// 反序列化
HotelDoc object = JSON.parseObject(json, HotelDoc.class);
list.add(object);
// 获取高亮结果
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if (!CollectionUtils.isEmpty(highlightFields)){
// 根据字段名获取高亮结果
HighlightField highlightField = highlightFields.get("name");
if (highlightFields != null){
// 获取高亮值
String name = highlightField.getFragments()[0].string();
// 覆盖非高亮结果
object.setName(name);
}
}
// System.out.println("object = " + object);
}
return new PageResult(value,list);
}
}
7、编写控制类,接收请求
java
@RestController
@RequestMapping("/hotel")
public class HotelController {
@Autowired
private IHotelService service;
@PostMapping("/list")
public PageResult search(@RequestBody RequestParams params){
return service.search(params);
}
}
8、运行代码,测试功能
(1)检索功能
(2)分页功能
二、添加品牌、城市、星级、价格等过滤功能
1、修改RequestParams类
java
@Data
public class RequestParams {
private String key;
private Integer page;
private Integer size;
private String sortBy;
private String city;
private String brand;
private String starName;
private Integer maxPrice;
private Integer minPrice;
}
2、更改service类
java
@Override
public PageResult search(RequestParams params) {
// 准备Request对象
try {
SearchRequest request = new SearchRequest("hotel");
buildBasicQuery(params, request);
// 分页
Integer page = params.getPage();
Integer size = params.getSize();
request.source().from((page-1)*size).size(size);
// 发送请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
return extracted(response);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void buildBasicQuery(RequestParams params, SearchRequest request) {
String key = params.getKey();
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
if (key==null || "".equals(key)){
boolQuery.must(QueryBuilders.matchAllQuery());
}else {
boolQuery.must(QueryBuilders.matchQuery("all", key));
}
// 城市条件
if (params.getCity() != null && !params.getCity().equals("")){
boolQuery.filter(QueryBuilders.termQuery("city", params.getCity()));
}
// 品牌条件
if (params.getBrand() != null && !params.getBrand().equals("")){
boolQuery.filter(QueryBuilders.termQuery("brand", params.getBrand()));
}
// 星级条件
if (params.getStarName() != null && !params.getStarName().equals("")){
boolQuery.filter(QueryBuilders.termQuery("starName", params.getStarName()));
}
// 价格
if (params.getMinPrice() != null && params.getMaxPrice() != null){
boolQuery.filter(QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));
}
// 准备DSL
request.source().query(boolQuery);
}
3、启动并测试
三、实现排序功能
1、修改RequestParams类
java
// 排序
String location = params.getLocation();
if (location != null && !location.equals("")){
request.source().sort(SortBuilders.geoDistanceSort("location",new GeoPoint(location))
.order(SortOrder.ASC)
.unit(DistanceUnit.KILOMETERS));
}
2、在PageResult类中增加排序算法
java
String location = params.getLocation();
if (location != null && !location.equals("")){
request.source().sort(SortBuilders.geoDistanceSort("location",new GeoPoint(location))
.order(SortOrder.ASC)
.unit(DistanceUnit.KILOMETERS));
}
3、修改HotelDoc类,增加Distance属性
java
private Object distance;
4、修改解析JSON的方法
java
// 获取排序值
Object[] sortValues = hit.getSortValues();
if (sortValues.length > 0){
Object sortValue = sortValues[0];
object.setDistance(sortValue);
}
四、实现广告置顶功能
1、修改HotelDoc类,增加isAD属性
java
private Boolean isAD;
2、在service实现类中添加算分方法
java
// 算分控制
FunctionScoreQueryBuilder functionScoreQuery = QueryBuilders.functionScoreQuery(
boolQuery,
new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
new FunctionScoreQueryBuilder.FilterFunctionBuilder(
QueryBuilders.termQuery("isAD","true"),//过滤条件
ScoreFunctionBuilders.weightFactorFunction(10) //分值*10
)
});