Elasticsearch显示不正确的距离

时间:2014-02-25 00:04:21

标签: elasticsearch

我有以下弹性搜索查询:

{
"from": 0,
"size": 10,
"fields": ["returnresults"],
"script_fields": {
    "distance": {
        "params": {
            "lat": -41.166670,
            "lon": 146.350000
        },
        "script": "doc[\u0027location\u0027].distanceInKm(lat,lon)"
    }
},
"track_scores": true,
"sort": [{
    "_geo_distance": {
        "searchindex.location": [146.350000,
        -41.166670],
        "order": "asc",
        "unit": "km"
    },
    "_score": {
        "order": "desc"
    }
}],
"query": {
    "query_string": {
        "query": "7383492",
        "fields": ["total"]
    }
},
"filter": {
    "and": [{
        "query": {
            "range": {
                "expiry": {
                    "gt": 1393285386
                }
            }
        }
    },
]
}
}

当我运行查询时,它会找到一些匹配的结果,但报告的距离是错误的。

对于coord海外地理编码:37.445796966553,-122.16209411621

返回结果为31145km。这是不可能的。

我在查询中做错了什么,或者这是弹性搜索本身的问题。我似乎没有短距离的问题,但可能是因为它距离很短,因此关闭的百分比很小。

我目前正在使用Elasticsearch 0.90.2

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

我很好奇这个问题是否得到了解答: Wrong distance returned by ElasticSearch distanceInKm 解决了这个问题。

我对这两种算法的快速而肮脏的测试得出的是平面距离= 19352英里(31144公里)和弧距= 7915.7英里(12739公里),所以它似乎确实很好地解释了所述的差异。无论如何我发现它很有趣,所以如果其他人感兴趣的话:

public static void main(String []args){
    double targetLongitude = 146.350000;
    double sourceLongitude = -122.16209411621;
    double targetLatitude = -41.166670;
    double sourceLatitude = 37.445796966553;
    double DISTANCE_PER_DEGREE = 69.16944444;
    double EARTH_RADIUS = 3958.76;

    //Plane distance
    double px = targetLongitude - sourceLongitude;
    double py = targetLatitude - sourceLatitude;
    double distanceMiles = Math.sqrt(px * px + py * py) * DISTANCE_PER_DEGREE;

    System.out.println(distanceMiles);


    //Arc distance
    double longitudeDifference = targetLongitude - sourceLongitude;
    double a = Math.toRadians(90D - sourceLatitude);
    double c = Math.toRadians(90D - targetLatitude);
    double factor = (Math.cos(a) * Math.cos(c)) + (Math.sin(a) * Math.sin(c) * Math.cos(Math.toRadians(longitudeDifference)));

    if (factor < -1D) {
        System.out.println( Math.PI * EARTH_RADIUS);
    } else if (factor >= 1D) {
        System.out.println(  0);
    } else {
        System.out.println(  Math.acos(factor) * EARTH_RADIUS);
    }
}