5月29日 00:51

Elasticsearch 如何实现地理空间搜索?

ES 通过 geo_point 和 geo_shape 两种类型支持地理搜索。geo_point 存储经纬度坐标点,支持 geo_distance(圆形范围)、geo_bounding_box(矩形范围)、geo_polygon(多边形范围)查询;geo_shape 存储复杂几何形状(线、多边形),支持相交、包含等空间关系查询。底层使用 geohash 编码将二维坐标映射为一维字符串,利用 BKD tree 索引加速范围检索。查询时先通过 geohash 前缀粗筛,再计算精确距离过滤。

追问

geo_point 和 geo_shape 怎么选?

存储门店位置等点数据用 geo_point,存储配送区域等面数据用 geo_shape。geo_point 查询更快,geo_shape 支持更复杂的空间关系但索引开销更大。

geo_distance 查询性能如何优化?

先用 geo_bounding_box 缩小候选集,再在结果上做精确距离计算。也可设置 geo_point 的 geohash_precision 控制索引精度。

经纬度顺序容易搞混怎么办?

ES 的 geo_point 支持多种格式:字符串 "lat,lon"、数组 [lon,lat](GeoJSON 标准)、对象 {lat,lon}。数组格式是 lon 在前,容易出错,推荐用对象格式避免歧义。

geohash 精度怎么选?

精度越高定位越准但索引越大。常见选择:1km 精度用 geohash_precision=5(约 4.9km 边长),100m 用 6,10m 用 7。业务精度需求决定精度设置。

geo 查询能和普通查询组合吗?

可以,放在 bool query 的 filter 子句中。geo 查询不计算评分,适合做过滤条件配合全文检索使用。

写段代码

json
PUT /stores { "mappings": { "properties": { "name": { "type": "keyword" }, "location": { "type": "geo_point" } } } } GET /stores/_search { "query": { "bool": { "filter": { "geo_distance": { "distance": "5km", "location": { "lat": 39.9, "lon": 116.4 } } } } } }
标签:ElasticSearch