Redis 7.x 系列【13】数据类型之地理位置(Geospatial)

发布于:2024-07-06 ⋅ 阅读:(19) ⋅ 点赞:(0)

有道无术,术尚可求,有术无道,止于术。

本系列Redis 版本 7.2.5

源码地址:https://gitee.com/pearl-organization/study-redis-demo

1. 概述

Geospatial 简称GEO,翻译过来是地理空间的意思,是 Redis 3.2 版本新增一种数据类型,底层的索引结构是 ZSet。主要用于存储地理位置信息,并对存储的信息进行操作。

2. 常用命令

所有命令:

命名 描述
GEOADD 将指定的地理空间位置(纬度、经度、名称)添加到指定的key
GEODIST 返回两个给定位置之间的距离
GEOHASH 返回一个或多个位置元素的 Geo hash 表示
GEOPOS key 里返回所有给定位置元素的位置(经度和纬度)
GEORADIUS 以给定的经纬度为中心, 找出某一半径内的元素
GEORADIUS_RO GEORADIUS 命令的只读变体,只是它不支持可选的 STORESTOREDIST 参数
GEORADIUSBYMEMBER 找出位于指定范围内的元素,中心点是由给定的位置元素决定
GEORADIUSBYMEMBER_RO GEORADIUSBYMEMBER 命令的只读变体,只是它不支持可选的 STORESTOREDIST 参数
GEOSEARCH 扩展了 GEORADIUS 命令,因此除了支持在圆形区域内搜索外,还支持在矩形区域内搜索
GEOSEARCHSTORE 类似于 GEOSEARCH,但它将结果存储在目标键中

2.1 GEOADD

GEOADD 用于将给定的空间元素(纬度、经度、名字)添加到指定的键中,这些数据会以有序集合的形式被储存。

命令语法:

GEOADD  key longitude latitude member [longitude latitude member ...]

注意事项:

  • GEOADD 命令以标准的 x,y 格式接受参数, 所以用户必须先输入经度, 然后再输入纬度。
  • GEOADD 能够记录的坐标是有限的,非常接近两极的区域是无法被索引的。

精确的坐标限制由 EPSG:900913 / EPSG:3785 / OSGEO:41001 等坐标系统定义, 具体如下:

  • 经度范围从-180度到180度。
  • 纬度范围从-85.05112878度到85.05112878度。
  • 当用户尝试输入一个超出范围的经度或者纬度时, GEOADD 命令将返回一个错误。

示例:

redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2
redis> GEODIST Sicily Palermo Catania
"166274.1516"
redis> GEORADIUS Sicily 15 37 100 km
1) "Catania"
redis> GEORADIUS Sicily 15 37 200 km
1) "Palermo"
2) "Catania"

2.2 GEODIST

GEODIST 命令用于返回两个给定位置之间的距离。

注意事项:

  • 如果两个位置之间的其中一个不存在, 那么命令返回空值。
  • 在计算距离时会假设地球为完美的球形, 在极限情况下, 这一假设最大会造成 0.5% 的误差。
  • 计算出的距离会以双精度浮点数的形式被返回。 如果给定的位置元素不存在, 那么命令返回空值。

命令语法:

GEODIST key member1 member2 [m|km|ft|mi]

参数说明:

  • member1 member2 :两个地理位置
  • [m|km|ft|mi]:距离单位,默认使用米作为单位
    • m :米,默认单位。
    • km :千米。
    • mi :英里。
    • ft :英尺。

示例:

redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2
redis> GEODIST Sicily Palermo Catania
"166274.1516"
redis> GEODIST Sicily Palermo Catania km
"166.2742"
redis> GEODIST Sicily Palermo Catania mi
"103.3182"
redis> GEODIST Sicily Foo Bar
(nil)

2.3 GEORADIUS

GEORADIUS 命令是用于根据给定的经纬度和半径,查询指定键中存储的地理位置信息的有序集合附近的元素。

允许你根据给定的经纬度和半径来查询附近的位置信息,并可以返回丰富的结果集,包括位置的经纬度、与查询点的距离以及Geohash值等。通过合理地使用这些选项,可以轻松地实现各种基于位置的搜索和查询功能。

命令语法:

GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]

参数说明:

  • keyRedis中存储地理位置信息的有序集合的名称。
  • longitudelatitude:查询点的经度和纬度。
  • radius:查询半径,可以指定单位(m表示米,km表示千米,ft表示英尺,mi表示英里)。
  • WITHCOORD:返回结果中包含元素的经纬度信息。
  • WITHDIST:返回结果中包含元素与查询点的距离。
  • WITHHASH:返回结果中包含元素的Geohash值。
  • COUNT count:限制返回结果的数量。
  • ASC|DESC:按距离排序结果,默认为升序(ASC),可选降序(DESC)。
  • STORE key:将结果存储到另一个键中,而不是直接返回。
  • STOREDIST key:将结果和对应的距离存储到另一个键中,结果是一个包含两个元素的数组(成员和距离)。

示例:

# 添加 Palermo、Catania的位置信息
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2
# 查询 15.37 200千米内的所有位置
redis> GEORADIUS Sicily 15 37 200 km WITHDIST
1) 1) "Palermo"
   2) "190.4424"
2) 1) "Catania"
   2) "56.4413"
redis> GEORADIUS Sicily 15 37 200 km WITHCOORD
1) 1) "Palermo"
   2) 1) "13.36138933897018433"
      2) "38.11555639549629859"
2) 1) "Catania"
   2) 1) "15.08726745843887329"
      2) "37.50266842333162032"
redis> GEORADIUS Sicily 15 37 200 km WITHDIST WITHCOORD
1) 1) "Palermo"
   2) "190.4424"
   3) 1) "13.36138933897018433"
      2) "38.11555639549629859"
2) 1) "Catania"
   2) "56.4413"
   3) 1) "15.08726745843887329"
      2) "37.50266842333162032"

2.4 GEOPOS

GEOPOS 命令用于从给定的 key 里返回所有指定名称的位置(经度和纬度),不存在的返回 nil

命令语法:

GEOPOS key member [member ...]

注意事项:

  • 因为该命令接受可变数量的位置元素作为输入, 所以即使用户只给定了一个位置元素, 命令也会返回数组回复。
  • GEOPOS 命令返回一个数组, 数组中的每个项都由两个元素组成: 第一个元素为给定位置元素的经度, 而第二个元素则为给定位置元素的纬度。 当给定的位置元素不存在时, 对应的数组项为 nil

示例:

redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2
redis> GEOPOS Sicily Palermo Catania NonExisting
1) 1) "13.36138933897018433"
   2) "38.11555639549629859"
2) 1) "15.08726745843887329"
   2) "37.50266842333162032"
3) (nil)

2.5 GEORADIUSBYMEMBER

GEORADIUSBYMEMBERGEORADIUS 命令一样, 都可以找出位于指定范围内的元素, 但是其中心点是由给定的位置元素(位置名称)决定的, 而不是使用经度和纬度来决定中心点。

基本语法:

GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]

示例:

redis> GEOADD Sicily 13.583333 37.316667 "Agrigento"
(integer) 1
redis> GEOADD Sicily 13.361389 38.115556 "Palermo" 15.087269 37.502669 "Catania"
(integer) 2
redis> GEORADIUSBYMEMBER Sicily Agrigento 100 km
1) "Agrigento"
2) "Palermo"

3. 应用场景

Geospatial 提供了对地理位置信息的存储和查询能力,常用于基于位置的服务(LBS),例如:

  • 查找附近的商家、餐馆、景点,社交网络中展示附近的人或活动。
  • 根据经纬度计算两点距离
  • 按照距离排序查询景点、商家等

在地图应用中,搜索附近酒店、美食店等是一个很常用的功能,例如,在火车站附近所有酒店时,默认会显示一公里之内的所有酒店并按照距离进行排序:

在这里插入图片描述
在实际应用场景中,Geospatial 只适用于简单定位功能,针对复杂的导航、路线规划等地图相关功能,请选择专业的第三方导航产品,比如百度、高德地图。


网站公告

今日签到

点亮在社区的每一天
去签到