弹性搜索中类似的sphinxsearch geodistance排序

时间:2017-07-25 13:12:55

标签: php sorting elasticsearch sphinx

我已使用名称进行聚合,但地理距离排序无法正常工作。 我已经实现了聚合和距离计算。但我不知道如何测量铲斗距离值。 请建议我如何实现?

映射: -

PUT /museums
{
    "mappings": {
        "doc": {
            "properties": {
                "location": {
                    "type": "geo_point"
                }
            }
        }
    }
}

数据值:

POST /museums/doc/_bulk?refresh
{"index":{"_id":1}}
{"location": "52.374081,4.912350", "name": "NEMO Science Museum"}
{"index":{"_id":2}}
{"location": "52.369219,4.901618", "name": "Museum Het Rembrandthuis"}
{"index":{"_id":3}}
{"location": "52.371667,4.914722", "name": "Nederlands Scheepvaartmuseum"}
{"index":{"_id":4}}
{"location": "51.222900,4.405200", "name": "Letterenhuis"}
{"index":{"_id":5}}
{"location": "48.861111,2.336389", "name": "Musée du Louvre"}
{"index":{"_id":6}}
{"location": "48.860000,2.327000", "name": "Musée d'Orsay"}
{"index":{"_id":7}}
{"location": "52.374081,4.912350", "name": "NEMO Science Museum"}
{"index":{"_id":8}}
{"location": "48.861111,2.336389", "name": "Musée du Louvre"}

弹性搜索查询:

POST /museums/_search?size=0
{
        "query": {

        },
        "sort": {
            "_geo_distance": {
                "location": {
                        "lat": 52.3760,
                        "lon": 4.894
                },
                "order": "asc",
                "unit": "km",
                "distance_type": "arc"
            }
        },
        "aggregations": {
            "by_id": {
                "terms": {
                    "field": "name.keyword",
                    "order": {
                      "_count": "asc"
                    },
                    "size": 20
                },
                "aggregations":{
                  "top":{
                    "top_hits":
                    {
                      "sort":{
                        "_geo_distance":{
"location":{"lat":19.143172,"lon":72.824966
                          }
              }
    }
}
}
}
}
}
}

以上查询给出结果但不按距离排序。

1 个答案:

答案 0 :(得分:0)

我可能误读了您,但您是想从另一个点获取X km /英里范围内的位置?

如果是这样,有一个叫做Haversine公式的公式,它使用球面三角法计算一定距离内的区域!它看起来像这样:

R = earth’s radius (mean radius = 6,371km)
Δlat = lat2− lat1
Δlong = long2− long1
a = sin²(Δlat/2) + cos(lat1).cos(lat2).sin²(Δlong/2)
c = 2.atan2(√a, √(1−a))
d = R.c
Angles need to be in radians to pass to Trigonometric functions

这对我来说都是非常数学的。但是在MySQL查询中,它看起来像这样:

SELECT *, 
 ( 3959 * acos( cos( radians(55.864237) ) * cos( radians( latitude ) ) 
 * cos( radians( longitude ) - radians(-4.251806) ) + sin( radians(55.864237) ) 
 * sin( radians( latitude ) ) ) ) AS distance 
FROM postcodes HAVING distance < 20 
ORDER BY distance LIMIT 1;

在这里,我检查20英里内的任何区域,但您可以根据需要将其缩短或缩短。查询开头的3959数字是用于里程的数字,如果你使用公里,你应该将这个数字更改为6371.我将它限制为1行,因为我只想要最接近的匹配,但是你可能想要在其他情况下改变这一点!