2014-01-06 56 views
3

在我的ElasticSearch索引中,位置是一個MultiValueField。當我爲涉及位置的文檔編寫自定義得分公式時,我希望腳本能夠在我查詢中最接近點的位置選取。計算MultiValueField位置上的距離

所以,我有我的得分公式中該部分:

... 
if (!doc['location'].empty && doc['location'].values.length > 1) { 
    least_distance = 10000; 
    foreach (loc_index: doc['location'].values) { 
     temp_distance = loc_index.distance(lat, lng); 
     if (temp_distance < least_distance) { 
      least_distance = temp_distance; 
     } 
... 

這不是最優雅的(我是新來的MVEL和ES),但在概念上,我第一次檢查,看看文檔[ '位置']確實有多個位置,如果是,則通過每個位置計算距離,並跟蹤迄今爲止發現的最小距離。

當我這樣做,ElasticSearch返回錯誤:

Query Failed [Failed to execute main query]]; nested: PropertyAccessException[[Error: unable to resolve method: org.elasticsearch.common.geo.GeoPoint.distance(java.lang.Double, java.lang.Double) 

我認爲意味着它不希望做一個GeoPoint,由於某種原因比不同.distance()字段,我可能通過執行doc ['location']。

我是否正確解釋了這種情況,並確實有人知道解決方法?有沒有一種方法可以使用ElasticSearch來計算距離(理想情況下無需實際計算兩個座標之間距離的所有算術)?

回答

4

問題在於撥打.values給出了GeoPoint()對象的列表。儘管我們需要做一些額外的工作來吸引適當的Java類,但還是有一個解決方法。我們需要有兩點的經度和緯度。

import org.elasticsearch.common.geo.GeoDistance; 
import org.elasticsearch.common.unit.DistanceUnit; 
base_point = doc['base_location'].value; 

if (!doc['location'].empty && doc['location'].values.length > 1) { 
    foreach (loc_index: doc['location'].values) { 
     distance = GeoDistance.PLANE.calculate(loc_index.lat, loc_index.lon, base_point.lat, base_point.lon, DistanceUnit.MILES);   
    } 
} 

我們可以通過可枚舉here所描述的不同單位得到結果。 我們也可以使用不同的計算方法(如ARC),如here所述。