Redis基础篇19 — geospatial特殊数据类型

基本地理知识

如同 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 命令

您可以使用一些网页工具来找到具体位置的经纬度,比如:

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

geosearchgeosearchstore 命令

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
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇