Redis的GEO功能在项目中实际的应用
最近项目中,有这样的一个需求:查找每个酒店最近的一个热点(地铁站、火车站、机场、景点),并显示与其距离。而项目正是采用Redis的GEO实现该功能。
Redis GEO 简介
Redis3.2版本提供了GEO(地理信息定位)功能,其支持存储地理位置信息用来实现诸如附近位置、摇一摇这类依赖于地理位置信息的功能。在使用层面,它像一种新的数据类型,但实际上它的类型为zset(Redis五种数据类型的其中之一),所以Redis的GEO可以像普通的zset的根据score排序那样支持地理位置排序。
Redis GEO 命令
增加地理位置信息 geoadd
语法:
geoadd key longitude latitude member [longitude latitude member ...]复制代码
用法:
# 添加key为hotarea, 经纬度为113.32 23.21的成员area1 geoadd hotarea 113.32 23.21 area1复制代码
注意:成功新增一个member,返回1;如果原来已存在member,则返回0,但会更新经纬度。
获取地理位置信息 geopos
语法:
geopos key member [member ...]复制代码
用法:
#获取hotarea的成员area1、area2经纬度信息 geopos hotarea area1 area2 # 返回结果如下: 1) 1) "113.42000037431716919" 2) "23.50999880475919213" 2) 1) "114.00000125169754028" 2) "24.00000096039796205"复制代码
获取两个地理位置的距离 geodist
语法:
geodist key member1 member2 [unit] # 说明:unit为距离单位,有如下单位: unit 单位 m 米(默认) km 千米 mi 英里 ft 尺复制代码
用法:
#获取hotarea的成员area1、area2之间的距离 geodist hotarea area1 area2 # 返回结果如下: "80353.7842"复制代码
注意:成功新增一个member,返回1;如果原来已存在member,则返回0,但会更新经纬度。
获取指定位置范围内的地理信息位置集合 georadius georadiusbymember
语法:
georadius key longitude latitude radius m|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key] # 或 georadiusbymember key member radius m|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key] [storedist key] # 说明: 可选参数,如下所示: ·withcoord:返回结果中包含经纬度。 withdist:返回结果中包含离中心节点位置的距离。 ·withhash:返回结果中包含geohash,有关geohash后面介绍。 ·COUNT count:指定返回结果的数量。 asc|desc:返回结果按照离中心节点的距离做升序或者降序。 ·store key:将返回结果的地理位置信息保存到指定键。 241 ·storedist key:将返回结果离中心节点的距离保存到指定键。复制代码
用法:
#获取hotarea中,距离经纬度『113.523 23.45』100公里以内的两个成员,并按距离从远到进排序,且返回其geohash值 georadius hotarea 113.523 23.45 100 km withcoord withdist withhash count 2 desc # 返回结果如下: 1) 1) "area2" 2) "78.1119" 3) (integer) 4047440636555553 4) 1) "114.00000125169754028" 2) "24.00000096039796205" 2) 1) "area1" 2) "12.4477" 3) (integer) 4046588309122289 4) 1) "113.42000037431716919" 2) "23.50999880475919213"复制代码
注意:store 选项不能与 withdist等选项一起使用,否则报错:ERR STORE option in GEORADIUS is not compatible with WITHDIST, WITHHASH and WITHCOORDS options
获取geohash(将二维经纬度转换为一维字符串) geohash
语法:
geohash key member [member ...]复制代码
用法:
geohash hotarea area1 # 返回结果如下: ) "ws0tszvgtt0"复制代码
特别说明:
geohash返回的字符串,两个字符串越相似,它们之间的距离越近,Redis利用字符串前缀匹配 算法实现相关的命令
Redis正是使用有序集合并结合geohash的特性实现了GEO的若干命令。
删除地理位置信息 zrem
语法:
zrem key member复制代码
用法:
zrem hotarea area2复制代码
项目中实际应用
需求:查找每个酒店最近的一个热点(地铁站、火车站、机场、景点),并显示与其距离。
实现逻辑:
通过geoadd将所有城市热点信息存入redis
通过georadius获取酒店最近的城市热点,其中count设置为1,排序设为asc,即可达到返回最近的城市热点效果。
作者:D调的蜀威
链接:https://juejin.cn/post/7023775719951958052