使用有序集合命令操作GEO数据

Redis 使用有序集合存储 GEO 数据,一个位置集合实际上就是一个有序集合:当用户调用 GEO 命令对位置集合进行操作时,这些命令实际上是在操作一个有序集合。

举个例子,当我们调用以下命令,将清远市的经纬度添加到 Guangdong-cities 位置集合时:

GEOADD Guangdong-cities 113.2099647 23.593675 Qingyuan

Redis 会把给定的经纬度转换成数字形式的 Geohash 值 4046597933543051,然后调用 ZADD 命令,将位置名及其 Geohash 值添加到有序集合中:

ZADD Guangdong-cities 4046597933543051 Qingyuan

除了 GEOADD 之外,包括 GEOPOS、GEODIST、GEORADIUS、 GEORADIUSBYMEMBER 和 GEOHASH 在内的所有 GEO 命令都是在有序集合的基础上实现的,这也使得我们可以直接使用有序集合命令对位置集合进行操作。

比如,可以使用 ZRANGE 命令查看位置集合存储的所有位置,以及这些位置的 Geohash 值:

redis> ZRANGE Guangdong-cities 0 -1 WITHSCORES
1) "Zhongshan" -- 位置
2) "4046330600091985" -- Geohash值
3) "Shenzhen"
4) "4046432447218769"
5) "Foshan"
6) "4046506835759376"
7) "Guangzhou"
8) "4046533621643967"
9) "Dongguan"
10) "4046540375616238"
11) "Qingyuan"
12) "4046597933543051"

或者使用 ZCARD 命令获取位置集合目前存储的位置数量:

redis> ZCARD Guangdong-cities
(integer) 6

还可以使用 ZSCORE 命令获取指定位置的数字 Geohash 值:

redis> ZSCORE Guangdong-cities Qingyuan
"4046597933543051"

此外,虽然 Redis 没有直接提供删除位置集合中指定位置的命令,但是我们可以使用 ZREM 命令达到相同的效果:

redis> GEOPOS Guangdong-cities Qingyuan
1) 1) "113.20996731519699097"
2) "23.59367501967128788"
redis> ZREM Guangdong-cities Qingyuan -- 删除位置集合中的Qingyuan位置
(integer) 1
redis> GEOPOS Guangdong-cities Qingyuan
1) (nil)