基本地理知识
如同 ES 中的 geo_point 字段类型,geospatial 是一种使用经纬度标识位置的数据类型。在一些使用地理位置定位的应用中特别常用,例如打车时的地理位置坐标、发快递时填写的发件人地址、外卖附近的店铺、地图中附近的加油站、汽车地图导航等等。
地球是一个三维的球体,但是人们为了标识地理位置的某一位置,使用了二维的坐标轴系统(横轴即经度,纵轴即纬度)来表示。纬度的范围为 [-90,90],经度的范围为 [-180,180]。这种将高维空间降低到低维空间的方式被称为 「降维」。
地理空间上的纬线与经线:
相关命令以及使用样例
主要的命令如下:
geoadd
– 添加一个或多个经纬度坐标,并定义相应的位置成员名称geopos
– 给定一个或多个成员名称,返回相关的经纬度geodist
– 查看两个经纬度坐标的距离,可指定距离单位georadius
– 以给定的经纬度为中心,返回与中心距离不超过给定距离的所有位置成员georadiusbymember
– 同 georadius,只不过将给定的经纬度换成已有的位置成员。该命令是 georadius 的拓展geosearch
– georadius 以圆形区域进行搜索,而 geosearch 则可以以矩形或圆形区域进行搜索,可以以给定的经纬度进行搜索,也可以以已有的位置成员进行搜索。geosearchstore
– 同 geosearch,只不过多了存储 key 的参数而已geohash
– 将一个或多个位置成员的经纬度使用 geohash 进行表示。geohash 是一种地址编码方法(算法),其实也就是「降维」,即将二维的坐标转换成一个一维的字符串,一维的字符串与二维的坐标是一种相互对应的映射关系。
geoadd
命令
您可以使用一些网页工具来找到具体位置的经纬度,比如:
- https://api.map.baidu.com/lbsapi/getpoint/index.html
- https://lbs.qq.com/getPoint/
- https://lbs.amap.com/tools/picker
geoadd 的用法:
命令的参数说明:
- NX – 不更新已有的位置成员,始终添加新位置成员;
- XX – 仅更新已存在的位置成员,比如有些位置成员的经纬度需要修改。
- CH – 默认情况下,使用 geoadd 命令返回新添加位置成员的总数量。若使用 CH ,则返回变更的位置成员总数,「变更的位置成员」指的是新添加的位置成员和已经更新坐标的位置成员。
注:NX 和 XX 参数是互斥的
在 Redis 中,可识别的经度范围为 [-180,180],可识别的纬度为 [-85.05112878,85.05112878]
# 添加4个位置成员
192.168.100.3:6379[9]> geoadd GuangZhou NX 113.331084 23.112223 "广州塔" 113.329428 23.111557 "广州塔地铁站-B口" 113.3311 23.112106 "广州塔-摩天轮" 113.329854 23.110414 "广州塔西"
(integer) 4
# 使用 NX 参数和 CH 参数更新已有位置成员的经纬度
192.168.100.3:6379[9]> geopos GuangZhou "广州塔西"
113.32985132932662964
23.11041522231636236
192.168.100.3:6379[9]> geoadd GuangZhou XX CH 113.32 23.110 "广州塔西"
1
192.168.100.3:6379[9]> geopos GuangZhou "广州塔西"
113.32000225782394409
23.10999952804623092
# 使用 type 命令可以看到,所谓的地理指标这种数据类型其实就是 zset
192.168.100.3:6379[9]> type GuangZhou
zset
## 这里碰到了中文乱码
192.168.100.3:6379[9]> zrange GuangZhou 0 -1 withscores
1) "\xe5\xb9\xbf\xe5\xb7\x9e\xe5\xa1\x94\xe8\xa5\xbf"
2) "4046534105969707"
3) "\xe5\xb9\xbf\xe5\xb7\x9e\xe5\xa1\x94\xe5\x9c\xb0\xe9\x93\x81\xe7\xab\x99-B\xe5\x8f\xa3"
4) "4046534149385861"
5) "\xe5\xb9\xbf\xe5\xb7\x9e\xe5\xa1\x94-\xe6\x91\xa9\xe5\xa4\xa9\xe8\xbd\xae"
6) "4046534150938448"
7) "\xe5\xb9\xbf\xe5\xb7\x9e\xe5\xa1\x94"
8) "4046534151113958"
# 只需要在 redis-cli 命令的后面添加 --raw 选项即可解决乱码问题
Shell > /usr/local/redis/bin/redis-cli -h 192.168.100.3 -p 6379 -a MyPassword --raw
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.100.3:6379> select 9
OK
192.168.100.3:6379[9]> zrange GuangZhou 0 -1 withscores
广州塔西
4046534105969707
广州塔地铁站-B口
4046534149385861
广州塔-摩天轮
4046534150938448
广州塔
4046534151113958
geopos
命令
返回一个或多个特定成员位置的经纬度。
192.168.100.3:6379[9]> geopos GuangZhou "广州塔" "广州塔-摩天轮"
113.33108514547348022
23.11222247850297151
113.33110123872756958
23.11210588132964006
geodist
命令
# 比如 广州塔 与 广州塔-摩天轮 这两个位置成员的距离,指定距离单位为米(M)
192.168.100.3:6379[9]> geodist GuangZhou "广州塔" "广州塔-摩天轮" M
13.0728
geohash
命令
# 返回相关位置成员的经纬度的 hash 值
192.168.100.3:6379[9]> geohash GuangZhou "广州塔地铁站-B口" "广州塔西"
ws0e6z7fx40
ws0e6xj1e20
georadius
命令
以给定的经纬度为中心,查找指定半径范围内的所有位置成员。这个命令的用法为:
参数说明:
- M|KM|FT|MI:距离的单位,分别指是米、千米、英尺、英里
- WITHCOORD:除了返回位置成员外,还将位置成员的经纬度也返回
- WITHDIST:除了返回位置成员外,还将位置成员的距离也返回
- WITHHASH:除了返回位置成员外,还返回位置成员的经纬度的整数 hash,通常在调试时会非常有用
- COUNT count:指定返回的位置成员的数量
- ASC|DESC:对距离进行排序,ASC即升序(从近到远),DESC即降序(从远到近)
- STORE key:将结果存储到指定的新 key 中,新 key 为 zset,成员的分值即原始的整数 hash。存储时不能有 WITHDIST、WITHHASH、WITHCOORD 参数
- STOREDIST key:将结果存储到指定的新 key 中,并同时存储位置与查询点的距离,成员的分值即距离的数字。存储时不能有 WITHDIST、WITHHASH、WITHCOORD 参数
192.168.100.3:6379[9]> GEORADIUS GuangZhou 113.330217 23.111855 500 M WITHCOORD WITHDIST WITHHASH COUNT 2 ASC
广州塔地铁站-B口 ← 位置成员
87.3471 ← 距离
4046534149385861 ← 原始的整数 hash
113.32942754030227661 ← 位置成员的经度
23.11155584683806552 ← 位置成员的纬度
广州塔-摩天轮
94.6632
4046534150938448
113.33110123872756958
23.11210588132964006
# 将结果保存到另外的新 key 上
192.168.100.3:6379[9]> GEORADIUS GuangZhou 113.330217 23.111855 500 M COUNT 2 ASC STORE newk1
2
192.168.100.3:6379[9]> type newk1
zset
192.168.100.3:6379[9]> zrange newk1 0 -1 withscores
广州塔地铁站-B口
4046534149385861
广州塔-摩天轮
4046534150938448
## 距离即分值
192.168.100.3:6379[9]> GEORADIUS GuangZhou 113.330217 23.111855 500 M COUNT 2 ASC STOREDIST newk2
2
192.168.100.3:6379[9]> type newk2
zset
192.168.100.3:6379[9]> zrange newk2 0 -1 withscores
广州塔地铁站-B口
87.34713640518257
广州塔-摩天轮
94.66320599236849
geosearch
和 geosearchstore
命令
geosearch 基本用法为:
参数说明:
- FROMMEMBER member:以已有的位置成员为中心开始搜索
- FROMLONLAT longitude latitude:以给定的经纬度为中心开始搜索
- BYRADIUS radius M|KM|FT|MI :指定圆的半径进行搜索
- BYBOX width height M|KM|FT|MI :指定矩形的长宽进行搜索
- COUNT count:指定返回的位置成员的数量
- WITHCOORD:除了返回位置成员外,还将位置成员的经纬度也返回
- WITHDIST:除了返回位置成员外,还将位置成员的距离也返回
- WITHHASH:除了返回位置成员外,还返回位置成员的经纬度的整数 hash,通常在调试时会非常有用
# 基于已有位置成员的圆形搜索
## 返回的一定包括位置成员本身
192.168.100.3:6379[9]> geosearch GuangZhou FROMMEMBER "广州塔" BYRADIUS 20 M ASC COUNT 2 WITHCOORD WITHDIST WITHHASH
广州塔 ← 位置成员
0.0000 ← 距离
4046534151113958 ← 原始的整数 hash
113.33108514547348022 ← 位置成员的经度
23.11222247850297151 ← 位置成员的纬度
广州塔-摩天轮
13.0728
4046534150938448
113.33110123872756958
23.11210588132964006
# 使用 geosearchstore 将结果保存在新的 key 中
## 保存的新 key 为 newk3
192.168.100.3:6379[9]> GEOSEARCHSTORE newk3 GuangZhou FROMMEMBER "广州塔" BYRADIUS 20 M ASC COUNT 2
2
192.168.100.3:6379[9]> type newk3
zset
## 以 整数hash 作为分值。您也可以在上一个命令的结尾加上 STOREDIST 参数,这样会保存距离作为分值
192.168.100.3:6379[9]> zrange newk3 0 -1 withscores
广州塔-摩天轮
4046534150938448
广州塔
4046534151113958
其他说明
Q:geospatial 貌似并没有提供删除位置成员的命令,怎么办?
前面 zset 提到有三种方式(或三个命令)可以对成员进行移除:
zrem
:直接以成员的名称进行移除,支持一个或多个zremrangebyrank
:指定索引排名的范围对成员进行移除zremrangebyscore
:指定分数的范围对成员进行移除,支持 -inf 和 +inf,也支持开区间 ( 符号
192.168.100.3:6379[9]> zrange GuangZhou 0 -1 withscores
广州塔西
4046534105969707
广州塔地铁站-B口
4046534149385861
广州塔-摩天轮
4046534150938448
广州塔
4046534151113958
# 按照成员名称删除
192.168.100.3:6379[9]> zrem GuangZhou "广州塔"
1
# 按照索引排名进行删除
192.168.100.3:6379[9]> zrange GuangZhou 0 -1
广州塔西 ←0
广州塔地铁站-B口 ←1
广州塔-摩天轮 ←2
192.168.100.3:6379[9]> zremrangebyrank GuangZhou 0 2
3
192.168.100.3:6379[9]> keys *
newk1
newk2
newk3
192.168.100.3:6379[9]> del newk1 newk2 newk3
3
版权声明:「自由转载-保持署名-非商业性使用-禁止演绎 3.0 国际」(CC BY-NC-ND 3.0)
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论