Redis GEO 特性(Redis版本>=3.2.0)支持对地理位置进行存储、空间索引、空间查询等相关操作。下面简要介绍其基本命令。
使用 GEOADD 添加位置
GEOADD 用于将给定的地理空间元素(纬度、经度、名称)添加到指定的集合(由key指定)中。Redis 内部会把对应的数据存储到一个 zset 有序集合中。存储时经纬度坐标会转换为 Geohash 值以实现空间索引,从而支持空间查询操作。
命令形式
1 | GEOADD key longitude latitude member [longitude latitude member ...] |
GEOADD 命令以 x,y 的格式接受经纬度参数,即经度在前,纬度在后。可以一次添加多个地理位置信息,即纬度、经度、名称可以重复多次。
GEOADD 支持的坐标范围是有限的,接近两极的坐标无法支持:
- 有效的经度介于 -180 度至 180 度之间。
- 有效的纬度介于 -85.05112878 度至 85.05112878 度之间。
GEOADD 每添加一个元素的时间复杂度为 O(log(N)) ,其中 N 为 key 对应的集合中的元素数量。
GEOADD 命令的返回值为新加入到集合中的地理空间元素的数量,集合中已存在的的元素(仅更新)不计入内。
示例
1 | redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania" |
使用 GEOPOS 获取位置
GEOPOS 用于从集合中获取指定元素的地理位置。
命令形式
1 | GEOPOS key member [member ...] |
GEOPOS 命令一次可指定多个元素,因此即使用户仅查询一个元素,该命令返回的也是数组。
返回的数组中,每项都由两个元素组成:第一个元素表示经度,而第二个元素表示纬度。当给定的位置元素不存在时,对应的数组项为空值。
GEOPOS 命令每查询一个元素的位置对应的时间复杂度为 O(log(N)) ,其中 N 是 key 对应的集合中的元素数量。
注意:由于存储的时候经纬度坐标被转换为 52位的 Geohash 值,因此存取过程中会引入误差,取回的经纬度可能和设置时的值略有差异。
示例
1 | redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania" |
使用 GEODIST 计算距离
GEODIST 命令可以计算集合中两个元素地理上的距离。
命令形式
1 | GEODIST key member1 member2 [unit] |
指定单位的参数 unit 必须是以下单位的其中一个:
- m 表示单位为米。
- km 表示单位为千米。
- mi 表示单位为英里。
- ft 表示单位为英尺。
如果没有指定单位,默认使用米作为单位。
计算得到的距离会以 double 值返回。如果给定的位置元素不存在,将返回空值。
使用 GEODIST 计算集合中两个元素的距离对应的时间复杂度为 O(log(N))
示例
1 | redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania" |
使用 GEORADIUS 或 GEORADIUSBYMEMBER 获取指定范围内的元素
GEORADIUS 和 GEORADIUSBYMEMBER 命令都可以用来查找指定范围内的元素。两者的不同在于指定中心点的方式。
命令形式
下面分别介绍 GEORADIUS 和 GEORADIUSBYMEMBER 的使用。
GEORADIUS
1 | GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count] |
GEORADIUS 命令以给定的经纬度为中心,在 key 对应的集合中查找距离该中心位置不超过 radius 指定的最大距离的所有元素。
支持的距离单位如下:
- m 表示单位为米。
- km 表示单位为千米。
- mi 表示单位为英里。
- ft 表示单位为英尺。
GEORADIUS 命令的时间复杂度为 O(N+log(M)), 其中 N 为指定半径范围的边界矩形内的元素数量,而 M 则是集合中元素的数量。
GEORADIUS 命令返回的一个数组,在没有 WITH 选项时返回的是一个简单的线性表,在指定了 WITHCOORD, WITHDIST, WITHHASH 等选项时, 返回的一个嵌套数组,内层的每个子数组表示一个元素。
选项
- WITHCOORD:同时返回元素的经纬度
- WITHDIST:同时返回元素离中心点的距离
- WITHHASH:同时返回 geohash 编码
- ASC:按离中心点距离由近到远排序
- DESC:按离中心点距离由远到近排序
- COUNT count:仅返回指定数量的元素,在范围内元素过多的时候,可以减少返回的元素,提高效率。
GEORADIUSBYMEMBER
1 | GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count] |
GEORADIUSBYMEMBER 命令和 GEORADIUS 命令一样,都是用来查找指定范围内的元素,不同的是 GEORADIUSBYMEMBER 的中心点是给定的集合中的元素对应的地理位置。
示例
下面分别举例说明 GEORADIUS 和 GEORADIUSBYMEMBER 的用法。
GEORADIUS
1 | redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania" |
GEORADIUSBYMEMBER
1 | redis> GEOADD Sicily 13.583333 37.316667 "Agrigento" |
使用 GEOHASH 获取 Geohash 表示
GEOHASH 命令用于获取集合中一个或多个元素的 Geohash 表示。
命令形式
1 | GEOHASH key member [member ...] |
GEOHASH 命令返回的是一个数组, 数组的每个项都是一个 geohash 。 命令返回的 geohash 的位置与用户给定的元素位置一一对应。
GEOHASH 命令获取每个元素的 Geohash 的时间复杂度为 O(log(N))
示例
1 | redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania" |
参考资料
https://redis.io/commands/geoadd
https://redis.io/commands/geodist
https://redis.io/commands/geopos