计算MultiValueField位置的距离

时间:2014-01-06 21:35:37

标签: elasticsearch mvel

在我的ElasticSearch索引中,location是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的新手),但从概念上讲,我首先要检查doc ['location']是否确实有多个位置,如果是,请通过每个位置计算距离,并跟踪到目前为止找到的最小距离。

当我这样做时,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计算距离(理想情况下没有实际为两个坐标之间的距离设置所有算术)?

1 个答案:

答案 0 :(得分: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