RedisSearch中的地理空间查询详解
RediSearch 项目地址: https://gitcode.com/gh_mirrors/red/RediSearch
概述
RedisSearch作为Redis的全文搜索模块,提供了强大的地理空间查询功能。本文将深入讲解如何使用RedisSearch进行地理空间数据查询,包括半径查询和形状查询两种主要方式。
地理空间数据类型
RedisSearch支持两种地理空间数据类型:
- GEO类型:用于存储简单的经纬度坐标点
- GEOSHAPE类型:用于存储更复杂的地理形状(需要Redis Stack 7.2.0及以上版本)
半径查询
半径查询是最基础的地理空间查询方式,用于查找指定中心点一定范围内的数据。
基本语法
FT.SEARCH 索引名 "@GEO字段:[经度 纬度 半径 单位]"
支持的单位
m
:米km
:千米mi
:英里ft
:英尺
实际示例
假设我们有一个自行车商店的索引,想要查找伦敦周围20英里内的所有商店:
FT.SEARCH idx:bicycle "@store_location:[-0.1778 51.5524 20 mi]"
这个查询会返回所有store_location
字段值在以伦敦坐标(-0.1778, 51.5524)为中心,20英里为半径的圆形区域内的记录。
形状查询
形状查询提供了更灵活的地理空间查询能力,支持点和多边形两种形状,以及两种空间关系判断。
基本语法
FT.SEARCH 索引名 "@GEOSHAPE字段:[{WITHIN|CONTAINS} $形状参数]" PARAMS 2 形状参数 "WKT格式的形状定义" DIALECT 3
关键概念解析
-
空间操作符:
WITHIN
:查找数据库中完全包含在给定形状内的形状CONTAINS
:查找数据库中包含给定形状的形状
-
WKT格式:
- 点:
POINT(经度 纬度)
- 多边形:
POLYGON((x1 y1, x2 y2, ..., x1 y1))
(注意首尾点要相同)
- 点:
-
DIALECT 3:
- 必须指定使用第三版查询方言才能支持形状查询
实际示例
示例1:检查自行车是否在取货区内
FT.SEARCH idx:bicycle "@pickup_zone:[CONTAINS $bike]" PARAMS 2 bike "POINT(-0.1278 51.5074)" DIALECT 3
这个查询会返回所有pickup_zone
包含给定坐标点(-0.1278, 51.5074)的记录。
示例2:查找欧洲范围内的所有取货区
FT.SEARCH idx:bicycle "@pickup_zone:[WITHIN $europe]" PARAMS 2 europe "POLYGON((-25 35, 40 35, 40 70, -25 70, -25 35))" DIALECT 3
这个查询定义了一个大致覆盖欧洲的多边形区域,返回所有完全位于该区域内的取货区。
最佳实践
-
数据建模:
- 对于简单的点位置查询,使用GEO类型
- 对于需要区域判断的场景,使用GEOSHAPE类型
-
性能考虑:
- 半径查询通常比形状查询更快
- 复杂多边形会降低查询性能
-
精度控制:
- 根据实际需求选择合适的查询精度
- 过高的精度要求会增加计算开销
常见问题解答
Q:如何判断该使用WITHIN还是CONTAINS?
A:这取决于你的查询意图。如果想找"在某个区域内的点",用WITHIN;如果想找"包含某个点的区域",用CONTAINS。
Q:多边形查询有什么限制?
A:目前只支持简单的多边形,不支持带孔的多边形或多边形集合。
Q:为什么我的形状查询没有返回结果?
A:首先检查是否指定了DIALECT 3,然后确认WKT格式是否正确,特别是多边形必须闭合。
通过本文的介绍,你应该已经掌握了RedisSearch中地理空间查询的核心概念和使用方法。这些功能可以广泛应用于位置服务、地理围栏、区域分析等各种场景。
RediSearch 项目地址: https://gitcode.com/gh_mirrors/red/RediSearch
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考