随着智能手机的普及,基于地理位置的服务变得越来越普遍。Redis3.2后就引入了Geo(地理位置)相关API,用于支持存储和查询这些地理位置的相关场景中的坐标。

相关命令

GEOADD、GEOPOS、GEORADIUS、GEODIST、GEORADIUSBYMEMBER、有序集合的命令都实用于Geo操作、GEOHASH

操作

1、使用GEOADD命令添加经纬度到集合中

127.0.0.1:6379> GEOADD geo_1 104.11359 30.61658 pos_1
(integer) 1
127.0.0.1:6379> GEOADD geo_1 104.1135900000 30.6165800000 pos_1 #存在相同的数据就返回0
(integer) 0
127.0.0.1:6379> GEOADD geo_1 104.1155755520 30.5880510097 pos_2
(integer) 1
127.0.0.1:6379> GEOADD geo_1 104.1407346725 30.6289758680 pos_3
(integer) 1

2、使用GEOPOS命令获取指定成员的坐标

127.0.0.1:6379> GEOPOS geo_1 pos_1
1) 1) "104.11358803510665894"
   2) "30.61657877614968726"
127.0.0.1:6379> GEOPOS geo_1 pos_2
1) 1) "104.11557823419570923"
   2) "30.58805048950133454"
127.0.0.1:6379> GEOPOS geo_1 pos_3
1) 1) "104.14073199033737183"
   2) "30.62897609734002202"

3、使用命令GEORADIUS根据某个经纬度获取小于某个范围内的其他位置信息

127.0.0.1:6379> GEORADIUS geo_1 104.0853309631 30.6283111619 10 km
1) "pos_2"
2) "pos_1"
3) "pos_3"
127.0.0.1:6379> GEORADIUS geo_1 104.0853309631 30.6283111619 5 km
1) "pos_1"
127.0.0.1:6379> GEORADIUS geo_1 104.0853309631 30.6283111619 1 km
(empty list or set)
127.0.0.1:6379> GEORADIUS geo_1 104.0853309631 30.6283111619 5320 m
1) "pos_1"
2) "pos_3"

127.0.0.1:6379> GEORADIUS geo_1 104.0853309631 30.6283111619 5320 km WITHDIST #使用WITHDIST获取距离信息
1) 1) "pos_2"
   2) "5.3326"
2) 1) "pos_1"
   2) "3.0030"
3) 1) "pos_3"
   2) "5.3029"
127.0.0.1:6379> GEORADIUS geo_1 104.0853309631 30.6283111619 5320 km WITHDIST DESC #再加上DESC|ASC进行排序
1) 1) "pos_2"
   2) "5.3326"
2) 1) "pos_3"
   2) "5.3029"
3) 1) "pos_1"
   2) "3.0030"

4、使用命令GEODIST获取两个位置的距离

127.0.0.1:6379> GEODIST geo_1 pos_1 pos_2 m
"3178.8109"
127.0.0.1:6379> GEODIST geo_1 pos_2 pos_3 km
"5.1497"
127.0.0.1:6379> GEODIST geo_1 pos_1 pos_3 km
"2.9413"

5、使用命令GEORADIUSBYMEMBER获取小于某个范围的位置,这个命令跟GEORADIUS功能一样,但是GEORADIUSBYMEMBER必须是Geo集合中的成员,而不像GEORADIUS可以随意指定,而且搜索出来的信息包含自己

127.0.0.1:6379> GEORADIUSBYMEMBER geo_1 pos_2 3 km
1) "pos_2"
127.0.0.1:6379> GEORADIUSBYMEMBER geo_1 pos_2 5 km
1) "pos_2"
2) "pos_1"

127.0.0.1:6379> GEORADIUSBYMEMBER geo_1 pos_2 5.2 km WITHDIST #使用WITHDIST获取距离信息
1) 1) "pos_2"
   2) "0.0000"
2) 1) "pos_1"
   2) "3.1788"
3) 1) "pos_3"
   2) "5.1497"
127.0.0.1:6379> GEORADIUSBYMEMBER geo_1 pos_2 5.2 km WITHDIST DESC #再加上DESC|ASC进行排序
1) 1) "pos_3"
   2) "5.1497"
2) 1) "pos_1"
   2) "3.1788"
3) 1) "pos_2"
   2) "0.0000"

当通过GEOADD命令设置坐标时,这些坐标会被内部转换成一个52位的GEOHASH。GEOHASH是一个被广泛使用的地理坐标编码系统。使用GEOADD添加的坐标信息跟GEOPOS命令返回的坐标之间存在细微的差别,但是这个没太大的影响。

GEORADIUS、GEORADIUSBYMEMBER命令都可以通过使用WITHDIST获取距离信息,并加上DESC|ASC进行排序。还可以使用STORE|STOREDIST选项将返回结果保存到里另一个Geo集合中。

注意:Geo集合实际上被存储在一个有序集合中,所以支持有序集合中的所有命令。如可以使用ZREM命令移除成员,也可以使用ZRANGE获取Geo集合的所有成员。

127.0.0.1:6379> ZRANGE geo_1 0 -1
1) "pos_2"
2) "pos_1"
3) "pos_3"
127.0.0.1:6379> ZREM geo_1 pos_1
(integer) 1
127.0.0.1:6379> ZRANGE geo_1 0 -1
1) "pos_2"
2) "pos_3"

7、GEOHASH的实现是基于一种52位整数的标识(实现了低于1米的精度)。当需要GEOHASH字符串是,可以使用GEOHASH命令来获取一个长度为11位的字符串

127.0.0.1:6379> GEOHASH geo_1 pos_2
1) "wm6n10qskc0"
127.0.0.1:6379> GEOHASH geo_1 pos_3
1) "wm6n1zbfwy0"