酒店数据全文检索练习(2)-按距离排序实现离我最近功能
前言
上一节(酒店数据全文检索练习(1)-关键词查询与结果条件过滤)我们讲了如何利用elasticsearch的关键词进行全文检索和数据过滤,这一节我们主要讲排序功能的实现
排序
地理位置排序
前端有一个功能,通过点击定位图标,会查询你当前的位置,并发送当前位置的请求到后台,我们可以根据这个实现我附近的酒店功能
这个字段是location,通过逗号分割的经纬度,我们在请求对象RequestParams
中添加这个字段
/**
* 当前定位
*/
private String location;
在前端中有一个distance
字段,来获取按距离排序后的结果,我们把这个字段加到返回对象HotelDoc
中
private Object distance;
然后我们修改HotelService
的list
方法
@Override
public ResponseObject list(RequestParams requestParams) {
SearchRequest request = new SearchRequest("hotel");
//构建BooleanQuery
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//构建查询语句
buildBasicQuery(requestParams, boolQuery);
request.source().query(boolQuery);
//分页
int page = requestParams.getPage();
int size = requestParams.getSize();
request.source().from((page - 1) * size).size(size);
// 排序
String location = requestParams.getLocation();
if (StringUtils.isNotEmpty(location)) {
request.source().sort(SortBuilders
.geoDistanceSort("location", new GeoPoint(location))
.order(SortOrder.ASC)
.unit(DistanceUnit.KILOMETERS) //单位:km
);
}
ResponseObject responseObject = new ResponseObject();
List<HotelDoc> hotelDocList = new ArrayList<>();
try {
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
long total = hits.getTotalHits().value;
responseObject.setTotal(total);
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {
HotelDoc hotelDoc = JSONObject.parseObject(searchHit.getSourceAsString(), HotelDoc.class);
//处理排序结果
Object[] sortValues = searchHit.getSortValues();
if (sortValues != null && sortValues.length != 0) {
hotelDoc.setDistance(sortValues[0]);
}
hotelDocList.add(hotelDoc);
}
responseObject.setHotels(hotelDocList);
} catch (IOException e) {
e.printStackTrace();
}
return responseObject;
}
重启项目,然后点击定位图标,可以看到如图标注的距离,但是由于数据中没有和我很近的数据,最近的都是深圳🤣
评价与价格排序
页面上还有两个排序方式,评价,价格 其实和距离排序差不多,评价,价格排序是通过前端sortBy
字段的值,后端判断用什么进行排序的
那么代码如下:
@Override
public ResponseObject list(RequestParams requestParams) {
SearchRequest request = new SearchRequest("hotel");
//构建BooleanQuery
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//构建查询语句
buildBasicQuery(requestParams, boolQuery);
request.source().query(boolQuery);
//分页
int page = requestParams.getPage();
int size = requestParams.getSize();
request.source().from((page - 1) * size).size(size);
// 排序
String location = requestParams.getLocation();
if (StringUtils.isNotEmpty(location)) {
request.source().sort(SortBuilders
.geoDistanceSort("location", new GeoPoint(location))
.order(SortOrder.ASC)
.unit(DistanceUnit.KILOMETERS) //单位:km
);
}
// 价格和评价分数排序
String sortBy = requestParams.getSortBy();
if (StringUtils.isNotEmpty(sortBy)){
if ("score".equals(sortBy)){
request.source().sort("score",SortOrder.ASC);
}else if ("price".equals(sortBy)){
request.source().sort("price",SortOrder.ASC);
}
}
ResponseObject responseObject = new ResponseObject();
List<HotelDoc> hotelDocList = new ArrayList<>();
try {
SearchResponse response = client.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
long total = hits.getTotalHits().value;
responseObject.setTotal(total);
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {
HotelDoc hotelDoc = JSONObject.parseObject(searchHit.getSourceAsString(), HotelDoc.class);
//处理排序结果
Object[] sortValues = searchHit.getSortValues();
if (sortValues != null && sortValues.length != 0) {
hotelDoc.setDistance(sortValues[0]);
}
hotelDocList.add(hotelDoc);
}
responseObject.setHotels(hotelDocList);
} catch (IOException e) {
e.printStackTrace();
}
return responseObject;
}
看看效果
大功告成,下一节(酒店数据全文检索练习(3)-定价排名广告置顶)我们讲竞价排名,将广告置顶。
酒店数据全文检索练习(2)-按距离排序实现离我最近功能
https://www.zhaojun.inkhttps://www.zhaojun.ink/archives/1011