3

In my ElasticSearch index, location is a MultiValueField. When I write a custom scoring formula for my documents involving location, I want the script to pick up on whichever location is the closest to the point in my query.

So, I have this part of my scoring formula:

...
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;
        }
...

It's not the most elegant (I'm new to mvel and ES), but conceptually I'm first checking to see if doc['location'] indeed has more than one location in it, and if so, go through each of the locations to calculate distance, and keep track of the minimum distance found so far.

When I do this, ElasticSearch is returning an error:

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)

which I think means that it doesn't want to do .distance() on a GeoPoint, which for some reason is different than a field that I might get by doing doc['location'].

Am I interpreting this situation correctly, and does anybody know of a workaround? Is there a way to just calculate distance (ideally without actually putting all the arithmetic for the distance between two coordinates) using ElasticSearch?

4

1 回答 1

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);         
    }
}

我们可以得到这里enumerable 描述的不同单位的结果。我们还可以使用此处描述的不同计算方法(如 ARC)。

于 2014-01-23T23:27:58.703 回答