2014-01-06 54 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所述。