elasticsearch根据地理坐标查询按照距离从近到远排序
功能需求
1. 查询方圆3000米范围内的所有用户/商户数据
2. 根据距离排序(查询我附近的用户/商户,按距离排序并显示距离,单位米(前端要传location字段))
/**
* 排序封装(查询我附近的用户/商户,按距离排序并显示距离,单位米(前端要传location字段))
*
* @param param
* @param request
*/
private void buildBasicSort(EsNearbyDTO param, SearchRequest request) {
// 查询我附近的用户/商户,并显示距离,单位米(前端要传location字段)
String location = NjBeanUtils.convertToFieldName(NearbyIndex::getLocation);
request.source().sort(SortBuilders
.geoDistanceSort(location, new GeoPoint(param.getLocation()))
.order(SortOrder.ASC)
.unit(DistanceUnit.METERS) //单位米
);
// 深度分页通过id排序,全局唯一值
if(param.getPage() == null || Constant.ZERO.equals(param.getPage())) {
String id = NjBeanUtils.convertToFieldName(NearbyIndex::getId);
request.source().sort(id, SortOrder.ASC);
}
}
/**
* 条件查询封装
*
* @param param
* @param request
*/
private void buildBasicQuery(EsNearbyDTO param, SearchRequest request) {
// 1.准备Boolean查询
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
// 用户ID/商户ID
if(param.getId() != null) {
boolQuery.filter(QueryBuilders.termQuery(NjBeanUtils.convertToFieldName(NearbyIndex::getId), param.getId()));
}
// 角色类型(0:用户,1:商户)
if(param.getRoleType() != null) {
boolQuery.filter(QueryBuilders.termQuery(NjBeanUtils.convertToFieldName(NearbyIndex::getRoleType), param.getRoleType()));
}
// 用户进来超过24小时后失效,数据不再显示
if(RoleTypeEnum.VIP.getCode().equals(param.getRoleType())) {
String expiryDate = NjBeanUtils.convertToFieldName(NearbyIndex::getExpiryDate);
boolQuery.filter(QueryBuilders.rangeQuery(expiryDate).gte(new Date().getTime()));
}
//按距离查询,单位米,eg:查询3000米范围内的数据
if(null != param.getDistance()) {
GeoDistanceQueryBuilder distanceQueryBuilder = new GeoDistanceQueryBuilder("location");
distanceQueryBuilder.point(new GeoPoint(param.getLocation()));
distanceQueryBuilder.distance(param.getDistance(), DistanceUnit.METERS);
boolQuery.filter(distanceQueryBuilder);
}
request.source().query(boolQuery);
}