elasticsearch距离排序和计算错误且不准确

时间:2015-12-19 15:12:24

标签: symfony elasticsearch geolocation

我正在使用elasticsearch来搜索网站上的搜索功能。搜索必须提供距离某个位置的距离搜索 - 例如 - 半径25公里。

这没问题,我正在使用以下elasticsearch查询数组:

编辑3 :使用function_score

更新了查询
{
    "index": "kasd9i9021profiles",
    "type": "profile",
    "size": 30,
    "from": 0,
    "body": {
    "query": {
        "function_score": {
            "functions": [
                {
                    "linear": {
                        "location": {
                            "origin": "49.449919468911,11.073560787681",
                            "offset": "2km",
                            "scale": "1km"
                        }
                    }
                }
            ],
            "score_mode": "avg",
            "boost_mode": "replace",
            "query": {
                "bool": {
                    "must": [
                        {
                            "term": {
                                "published": "1"
                            }
                        },
                        {
                            "match": {
                                "country": "DE"
                            }
                        }
                    ],
                    "filter": {
                        "geo_distance": {
                            "distance": "25km",
                            "distance_type": "arc",
                            "_cache": true,
                            "location": {
                                "lat": 49.449919468911,
                                "lon": 11.073560787681
                            },
                            "unit": "km"
                        }
                    }
                }
            }
        }
    },
    "aggs": {
        "rings": {
            "geo_distance": {
                "field": "location",
                "origin": "49.449919468911,11.073560787681",
                "distance_type": "arc",
                "unit": "km",
                "ranges": [
                    {
                        "to": 25
                    }
                ]
            }
        }
    },
    "script_fields": {
        "distance": {
            "lang": "groovy",
            "params": {
                "lat": 49.449919468911,
                "lon": 11.073560787681
            },
            "script": "doc['location'].distanceInKm(lat,lon)"
        }
    },
    "sort": [
        {
            "upgrade_sort": {
                "order": "desc"
            }
        },
        {
            "has_siegel": {
                "order": "desc"
            }
        },
        {
            "_geo_distance": {
                "location": {
                    "lat": 49.449919468911,
                    "lon": 11.073560787681
                },
                "order": "desc",
                "unit": "km"
            }
        }
    ]
    },
    "fields": [
    "_source",
    "distance"
    ]
}

“upgrade_sort”的值可以在0到3之间。 “has_siegel”的值可以是true或false。

问题是:

  1. 结果未按距离排序
  2. 结果中的距离介于0到30km之间,而不是介于0到25km之间。
  3. 这是错误还是错误的查询?

    编辑1

    映射:

    $params = [
        'index' => $name,
        'body' => [
            'mappings' => [
                'profile' => [
                    'properties' => [
                        'name' => [
                            'type' => 'string',
                        ],
                        'logo_url' => [
                            'type' => 'string',
                        ],
                        'foto_url' => [
                            'type' => 'string',
                        ],
                        'info_text' => [
                            'type' => 'string',
                        ],
                        'cPerson' => [
                            'type' => 'string',
                        ],
                        'street' => [
                            'type' => 'string',
                        ],
                        'city' => [
                            'type' => 'string',
                        ],
                        'country' => [
                            'type' => 'string',
                        ],
                        'website' => [
                            'type' => 'string',
                        ],
                        'location' => [
                            'type' => 'geo_point'
                        ],
                        'upgrade_sort' => [
                            'type' => 'integer'
                        ],
                    ]
                ]
            ]
        ]
    ];
    

    结果:出于隐私原因,我无法公布完整结果。这是距离细节:

    编辑2

    协调addet

    distance: 9,82km
    has_siegel: 0
    upgrade_sort: 3
    lon: 10.988270100000022
    lat: 49.4724229
    
    distance: 10,87km
    has_siegel: 0
    upgrade_sort: 2
    lon: 10.980907500000058
    lat: 49.4808363
    
    distance: 15,71km
    has_siegel: 0
    upgrade_sort: 1
    lon: 11.017770000000041
    lat: 49.5795
    
    distance: 0,15km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.072768300000007
    lat: 49.4488594
    
    distance: 0,32km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.07072740000001
    lat: 49.44968069999999
    
    distance: 0,32km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.07072740000001
    lat: 49.44968069999999
    
    distance: 0,47km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.077651400000036
    lat: 49.4487752
    
    distance: 0,60km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.078965499999981
    lat: 49.4501188
    
    distance: 0,61km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.078960000000052
    lat: 49.45074
    
    distance: 0,56km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.076950099999976
    lat: 49.4536002
    
    distance: 0,83km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.080846599999973
    lat: 49.4483038
    
    distance: 0,70km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.07790239999997
    lat: 49.45442389999999
    
    distance: 0,70km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.07790239999997
    lat: 49.45442389999999
    
    distance: 0,94km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.065464399999996
    lat: 49.4475953
    
    distance: 0,72km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.075771300000042
    lat: 49.4560251
    
    distance: 1,14km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.066973200000007
    lat: 49.4578074
    
    distance: 1,40km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.084297399999969
    lat: 49.4563874
    
    distance: 1,23km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.077985799999965
    lat: 49.4397852
    
    distance: 1,41km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.081709400000022
    lat: 49.440276
    
    distance: 1,51km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.067300100000011
    lat: 49.4619894
    
    distance: 2,48km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.092409999999973
    lat: 49.4618
    
    distance: 3,65km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.104663200000005
    lat: 49.4602779
    
    distance: 3,74km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.100480000000061
    lat: 49.47002
    
    distance: 4,12km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.043360000000007
    lat: 49.42859
    
    distance: 4,16km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.100729999999999
    lat: 49.47564
    
    distance: 5,61km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.032510600000023
    lat: 49.4207607
    
    distance: 5,41km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.093795699999987
    lat: 49.4057095
    
    distance: 6,60km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.033873800000038
    lat: 49.4058283
    
    distance: 7,51km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.016179100000045
    lat: 49.4143705
    
    distance: 7,49km
    has_siegel: 0
    upgrade_sort: 0
    lon: 11.130335599999967
    lat: 49.41382410000001 
    

2 个答案:

答案 0 :(得分:0)

您的过滤器仅排除不在25公里半径范围内的结果。如果要按距离对结果进行排序,则必须使用function score query with a decay function

对于距离,如果您希望它更准确,如文档中所述,您应该使用the arc distance_type

答案 1 :(得分:0)

我刚刚得到了解决方案:将doc['location'].distanceInKm(lat,lon)转为doc['location'].arcDistanceInKm(lat,lon)

在文档中不容易找到,但elasticsearch的开发者会更新它:https://github.com/elastic/elasticsearch/issues/15616