计算多值字段位置上的距离



在我的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上执行.dancee(),由于某种原因,这与我通过执行doc["location"]可能获得的字段不同。

我对这种情况的解释正确吗?有人知道变通办法吗?有没有一种方法可以使用ElasticSearch计算距离(理想情况下不需要实际计算两个坐标之间的距离)?

这里的问题是调用.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);         
}
}

我们可以用这里的可枚举数描述的不同单位得到结果。我们还可以使用不同的计算方法(如ARC),如下所述。

最新更新