地理距離過濾器
(geo_distance
)以給定位置為圓心畫一個圓,來找出那些位置落在其中的文檔:
GET /attractions/restaurant/_search
{
"query": {
"filtered": {
"filter": {
"geo_distance": {
"distance": "1km", <1>
"location": { <2>
"lat": 40.715,
"lon": -73.988
}
}
}
}
}
}
找出所有與指定點距離在1公里(`1km`)內(nèi)的 `location` 字段。訪問 [Distance Units](http://bit.ly/1ynS64j) 查看所支持的距離表示單位
地理距離過濾器計算代價昂貴。 為了優(yōu)化性能,Elasticsearch 先畫一個矩形框(邊長為2倍距離)來圍住整個圓形, 這樣就可以用消耗較少的盒模型計算方式來排除掉那些不在盒子內(nèi)(自然也不在圓形內(nèi))的文檔, 然后只對落在盒模型內(nèi)的這部分點用地理坐標(biāo)計算方式處理。
提示
你需要判斷你的使用場景,是否需要如此精確的使用圓模型來做距離過濾? 通常使用矩形模型是更高效的方式,并且往往也能滿足應(yīng)用需求。
兩點間的距離計算,有多種性能換精度的算法:
arc
::
最慢但是最精確是弧形
(arc
)計算方式,這種方式把世界當(dāng)作是球體來處理。
不過這種方式精度還是有限,因為這個世界并不是完全的球體。
plane
::
平面
(plane
)計算方式,((("plane distance calculation")))把地球當(dāng)成是平坦的。
這種方式快一些但是精度略遜;在赤道附近位置精度最好,而靠近兩極則變差。
sloppy_arc
::
如此命名,是因為它使用了 Lucene 的 SloppyMath
類。
這是一種用精度換取速度的計算方式,它使用 Haversine formula 來計算距離;
它比弧形
(arc
)計算方式快4~5倍, 并且距離精度達(dá)99.9%。這也是默認(rèn)的計算方式。
你可以參考下例來指定不同的計算方式:
GET /attractions/restaurant/_search
{
"query": {
"filtered": {
"filter": {
"geo_distance": {
"distance": "1km",
"distance_type": "plane", <1>
"location": {
"lat": 40.715,
"lon": -73.988
}
}
}
}
}
}
提示: 你的用戶真的會在意一個賓館落在指定圓形區(qū)域數(shù)米之外了嗎? 一些地理位置相關(guān)的應(yīng)用會有較高的精度要求;但大部分實際應(yīng)用場景中,使用精度較低但響應(yīng)更快的計算方式可能就挺好。
地理距離過濾器
(geo_distance
)和地理距離區(qū)間過濾器
(geo_distance_range
)的唯一差別在于后者是一個環(huán)狀的,它會排除掉落在內(nèi)圈中的那部分文檔。
指定到中心點的距離也可以換一種表示方式:
指定一個最小距離(使用 gt
或者gte
)和最大距離(使用lt
或者lte
),就像使用區(qū)間
(range
)過濾器一樣。
GET /attractions/restaurant/_search
{
"query": {
"filtered": {
"filter": {
"geo_distance_range": {
"gte": "1km", <1>
"lt": "2km", <1>
"location": {
"lat": 40.715,
"lon": -73.988
}
}
}
}
}
}