如何使用Elasticsearch地理查询获取给定geo point最近的地理位置点
Elasticsearch获取最近地理点的实现方案
方案1:直接按地理距离排序(全版本兼容,最易用)
你不需要用geo_distance查询做过滤,直接对全部文档按到目标点的距离排序,取前N条结果即可,完全不需要预先指定搜索半径:
GET /你的索引名/_search { "size": 1, // 要返回的最近点数量,取最近1个就填1 "query": { "match_all": {} // 有其他过滤条件可以替换此处,没有就保留match_all }, "sort": [ { "_geo_distance": { "你的geo_point字段名": { // 你存储地理坐标的字段名 "lat": 目标纬度, "lon": 目标经度 }, "order": "asc", // 升序即按距离从近到远返回 "unit": "km", // 距离返回单位,可选km、m等 "distance_type": "arc" // 球面距离计算,精度最高,默认值即可 } } ] }
该方案无需额外配置,兼容所有支持geo_point类型的ES版本,适合数据量不大、对查询性能要求不极端的场景。
方案2:k近邻(kNN)搜索(高性能,ES 7.10+版本支持)
如果你的数据量较大,全量排序查询延迟偏高,可以用ES原生的kNN搜索能力,该能力针对查找最近N个点的场景做了专门优化,查询效率比全量排序高1~2个数量级:
GET /你的索引名/_search { "size": 1, "knn": { "field": "你的geo_point字段名", "k": 1, // 返回最近的k个点 "num_candidates": 100, // 每个分片的候选点数量,值越大精度越高、性能略有下降 "query_vector": [目标经度, 目标纬度] // 注意顺序为经度在前,纬度在后 } }
该方案适合千万级以上geo_point数据的查询场景。
补充说明
- 两种方案都会在返回结果的
sort字段中直接附带计算好的距离值,不需要额外开发距离计算逻辑 - 如果后续需要叠加其他过滤规则(比如仅查询某类属性的点位),在
query参数中添加对应过滤条件即可,不会影响距离排序的逻辑
内容的提问来源于stack exchange,提问作者yasithlokuge
相关产品推荐
相关产品推荐

