1. 程式人生 > >ElasticSearchTemplate實現給定經緯度的“離我最近”排序/按距離排序

ElasticSearchTemplate實現給定經緯度的“離我最近”排序/按距離排序

按步驟來吧。

第一步,準備要使用此排序方式的、要存入ES的Bean,新增位置資訊屬性,並加 @GeoPointField 。位置屬性的型別為GeoPoint。正常情況下應該是用SpringData包下的GeoPoint型別,但是使用期間會出現各種無法判斷的錯誤,所以我們一般自己建立一個GeoPoint類,這個類需要有lat(緯度)和lon(經度)這兩個屬性、兩個構造器(空參、全參),和屬性的getter setter。

// 自己建立的GeoPoint
public class GeoPoint {
    private Double lat, lon;
    public GeoPoint() {
    }
    public GeoPoint(Double lat, Double lon) {
        this.lat = lat;
        this.lon = lon;
    }
    public Double getLat() {
        return lat;
    }
    public void setLat(Double lat) {
        this.lat = lat;
    }
    public Double getLon() {
        return lon;
    }
    public void setLon(Double lon) {
        this.lon = lon;
    }
}
// 要排序的JavaBean
public class Shop{
    @Id
    private Integer shopId;
    @GeoPointField
    private GeoPoint position;
}
//多餘的就不寫了

第二步就是把物件存到ElasticSearch中,這篇文章僅針對“離我最近”排序,如何存入不再贅述。存入之後,在Kibana中看到的位置資訊是這樣顯示的:

"shopId":201805111234567,
"position":{
    "lat":40.123,
    "lon":-70.456
}

第三步,就是排序並查詢了,程式碼如下:

NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder().withQuery(boolQueryBuilder).withPageable(pageable);
if (null != searchParams.getSortType() && SortTypeConstants.DISTANCE.getCode() == searchParams.getSortType()) {
    GeoDistanceSortBuilder sortBuilder = SortBuilders.geoDistanceSort("position", "")
    .point(searchParams.getLat(), searchParams.getLon())
    .unit(DistanceUnit.METERS)
    .order(SortOrder.ASC);
    nativeSearchQueryBuilder.withSort(sortBuilder);
}
SearchQuery searchQuery = nativeSearchQueryBuilder.build();

boolQueryBuilder在前面建立好的,用來拼接篩選條件,我的其它文章有介紹。按距離排序需要建立NativeSearchQueryBuilder,然後.withSort()就可以了。

經緯度和排序型別都是放在searchParams裡面的,這個沒有死規定,可以自行定義。

這樣就完成了“離我最近”的排序。