Redis 的 GEO是在3.2版本才有的 官方说明:Redis 3.2 contains significant changes to the API and implementation of Redis. A new set of commands for Geo indexing was added (GEOADD, GEORADIUS and related commands).
Redis GEO实现主要包含了以下两项技术: 使用geohash保存地理位置的坐标。 使用有序集合(zset)保存地理位置的集合。
GEOADD 增加某个地理位置的坐标; GEOPOS 获取某个地理位置的坐标; GEODIST 获取两个地理位置的距离; GEORADIUS 根据给定地理位置坐标获取指定范围内的地理位置集合; GEORADIUSBYMEMBER 根据给定地理位置获取指定范围内的地理位置集合; GEOHASH 获取某个地理位置的geohash值。
1.GEOADD 添加地理位置 GEOADD key longitude latitude member [longitude latitude member ...]
将给定的空间元素(纬度、经度、名字)添加到指定的键里面。 这些数据会以有序集合的形式被储存在键里面, 从而使得像 GEORADIUS 和 GEORADIUSBYMEMBER 这样的命令可以在之后通过位置查询取得这些元素。
GEOADD 命令以标准的 x,y 格式接受参数, 所以用户必须先输入经度, 然后再输入纬度。 GEOADD 能够记录的坐标是有限的: 非常接近两极的区域是无法被索引的。 有效的经度介于 -180 度至 180 度之间。 有效的纬度介于 -85.05112878 度至 85.05112878 度之间。 当用户尝试输入一个超出范围的经度或者纬度时, GEOADD 命令将返回一个错误。 127.0.0.1:6379> geoadd user 116.38829803467 39.928901672363 "xiaoming" 121.4691562490 31.2323076784 "xiaohong" (integer) 2
2.GEOPOS 获取某个地理位置的坐标; GEOPOS key member [member ...] 从键里面返回所有给定位置元素的位置(经度和纬度)。
GEOPOS 命令返回一个数组, 数组中的每个项都由两个元素组成: 第一个元素为给定位置元素的经度, 而第二个元素则为给定位置元素的纬度。 当给定的位置元素不存在时, 对应的数组项为空值。
127.0.0.1:6379> geopos user xiaoming 1) 1) "116.38829803467" 2) "39.928901672363"
3.GEODIST 获取两个地理位置的距离; GEODIST key member1 member2 [unit]
如果两个位置之间的其中一个不存在, 那么命令返回空值。
指定单位的参数 unit 必须是以下单位的其中一个: m 表示单位为米。 km 表示单位为千米。 mi 表示单位为英里。 ft 表示单位为英尺。 如果用户没有显式地指定单位参数, 那么 GEODIST 默认使用米作为单位。 GEODIST 命令在计算距离时会假设地球为完美的球形, 在极限情况下, 这一假设最大会造成 0.5% 的误差。 127.0.0.1:6379> geodist user xiaoming xiaohong m "1070429.1913"
4.GEORADIUS 根据给定地理位置坐标获取指定范围内的地理位置集合; GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]
范围可以使用以下其中一个单位: m 表示单位为米。 km 表示单位为千米。 mi 表示单位为英里。 ft 表示单位为英尺。 在给定以下可选项时, 命令会返回额外的信息:
WITHDIST : 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。 WITHCOORD : 将位置元素的经度和维度也一并返回。 WITHHASH : 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大。 命令默认返回未排序的位置元素。 通过以下两个参数, 用户可以指定被返回位置元素的排序方式:
ASC : 根据中心的位置, 按照从近到远的方式返回位置元素。 DESC : 根据中心的位置, 按照从远到近的方式返回位置元素。 在默认情况下, GEORADIUS 命令会返回所有匹配的位置元素。 虽然用户可以使用 COUNT <count> 选项去获取前 N 个匹配元素, 但是因为命令在内部可能会需要对所有被匹配的元素进行处理, 所以在对一个非常大的区域进行搜索时, 即使只使用 COUNT 选项去获取少量元素, 命令的执行速度也可能会非常慢。 但是从另一方面来说, 使用 COUNT 选项去减少需要返回的元素数量, 对于减少带宽来说仍然是非常有用的。
127.0.0.1:6379> georadius user 120 35 800 km WITHDIST 1) 1) "xiaoming" 2) "634.0595" 2) 1) "xiaohong" 2) "440.8323"
5.GEORADIUSBYMEMBER 根据给定地理位置获取指定范围内的地理位置集合; GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]
这个命令和 GEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是 GEORADIUSBYMEMBER 的中心点是由给定的位置元素决定的, 而不是像 GEORADIUS 那样, 使用输入的经度和纬度来决定中心点。 GEORADIUSBYMEMBER可以根据给定地理位置获取指定范围内的地理位置集合。GEORADIUS命令传递的是坐标,GEORADIUSBYMEMBER传递的是地理位置。GEORADIUS更为灵活,可以获取任何坐标点范围内的地理位置。但是大多数时候,只是想获取某个地理位置附近的其他地理位置,使用GEORADIUSBYMEMBER则更为方便
127.0.0.1:6386> georadiusbymember user xiaoming 1500 km WITHDIST 1) 1) "xiaohong" 2) "1070.4292" 2) 1) "xiaoming" 2) "0.0000"
6.GEOHASH 获取某个地理位置的geohash值。 GEOHASH key member [member ...]
GEOHASH 命令返回一个数组, 数组的每个项都是一个 geohash 。 命令返回的 geohash 的位置与用户给定的位置元素的位置一一对应。
127.0.0.1:6386> geohash user xiaoming 1) "wx4g0kz6ey0"
4.应用场景: LBS(Location Based Service)基于位置的服务,它是通过电信移动运营商的无线电通讯网络(如GSM网、CDMA网)或外部定位方式(如GPS)获取移动终端用户的位置信息(地理坐标,或大地坐标) 常见的有,附近的位置,附近的人,摇一摇,获取两点之间的距离等等