在我的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计算距离(理想情况下没有实际为两个坐标之间的距离设置所有算术)?
答案 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);
}
}