Redis特殊数据类型:Geospatial

Geospatial

一、类型概述

Geospatial 是 Redis 在 3.2 版本中新增的一种数据类型。它并不是一种全新的底层数据结构,而是基于 Sorted Set(有序集合) 实现的功能扩展。

它专门用于存储和操作地理位置信息,允许你存储经纬度坐标,并基于这些坐标进行复杂的计算,例如:

  • 计算两个位置之间的距离。
  • 查找某个指定点半径内的所有其他位置。
  • 获取位置的 Geohash 值。

二、基本方法

[ ]是可选的意思

1. 添加方法

geoadd key [NX|XX] [CH] longitude latitude member [longitude latitude member ...]

bash 复制代码
[NX|XX] [CH]的描述详见ZSet  longitude经度  latitude纬度
有效的经度范围是从-180 到 180 度。
有效的纬度范围是从-85.05112878 到 85.05112878 度。
127.0.0.1:6379> geoadd people 100.45 10.04 p1 155.20 11.34 p2 80.55 40.99 p3 105.49 33.50 p4
(integer) 4

2. 查找方法 geopos key [member [member ...]]

bash 复制代码
127.0.0.1:6379> geopos people p1 p2 p3 p4
1) 1) "100.45000165700912"
   2) "10.03999882812709"
2) 1) "155.19999772310257"
   2) "11.339999012165372"
3) 1) "80.55000096559525"
   2) "40.99000116237913"
4) 1) "105.490001142025"
   2) "33.499998990657744"

3. 返回两个位置之间的距离geodist key member1 member2 [M|KM|FT|MI] [M|KM|FT|MI]表示单位

bash 复制代码
127.0.0.1:6379> geodist people p1 p2 km
"5976.9722"

4. GEOSEARCH key <FROMMEMBER member | FROMLONLAT longitude latitude> <BYRADIUS radius unit | BYBOX width height unit> [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]

注意要求(Redis 6.2+)

作用: 用于在一个地理空间索引(即一个特殊的 Sorted Set)中搜索位于指定形状(圆形或矩形)和中心点范围内的所有位置元素。

  • 参数解析

      1. 指定要搜索的 Key (key)

    这是你之前使用 GEOADD 添加了地理位置数据的那个键。
    *
    2. 指定搜索的中心点 (<FROMMEMBER | FROMLONLAT>) 你必须从这两个选项中二选一,以确定搜索的圆心或矩形的中心。

    • FROMMEMBER member

      使用指定 member(即已存在于 key 中的地点名称)的坐标作为中心点。

      示例: FROMMEMBER "Beijing" 表示以"北京"这个地点的坐标为中心进行搜索。

    • FROMLONLAT longitude latitude

      使用你自己提供的经纬度坐标作为中心点。

      示例: FROMLONLAT 116.40 39.90 表示以经度116.40,纬度39.90这个点为中心进行搜索。

      1. 指定搜索区域的形状 (<BYRADIUS | BYBOX>) 你必须从这两个选项中二选一,以确定搜索区域的边界。
      • BYRADIUS radius unit

        在一个圆形区域内进行搜索。

        radius: 半径数值。

        unit: 单位,可以是 m(米), km(千米), mi(英里), ft(英尺)。

        示例: BYRADIUS 100 km 表示在半径为100公里的圆形区域内搜索。

      • BYBOX width height unit

        在一个轴对齐的矩形(即南北/东西方向的矩形,不是旋转的)区域内进行搜索。

        width: 矩形从中心向东 西延伸的距离(即宽度是 2 * width)。

        height: 矩形从中心向北 南延伸的距离(即高度是 2 * height)。

        unit: 单位,同上。

        示例: BYBOX 50 30 km 表示搜索一个东西宽100公里(中心点左右各50公里)、南北长60公里(中心点上下各30公里)的矩形区域。

      1. 指定返回的附加信息 ([WITH*] 选项)

      这些是可选的,用于控制返回结果的丰富程度。

      • WITHCOORD

        在结果中一并返回匹配项的经纬度坐标。

      • WITHDIST

        在结果中一并返回匹配项与中心点的距离。

      • WITHHASH

        在结果中一并返回匹配项原始的 Geohash 整数值(52位整数)。这通常用于调试,一般业务场景用不到。

      1. 限制和排序结果 ([COUNT] [ASC|DESC])

        这些也是可选的,用于对结果集进行筛选和排序。

        • COUNT count

        限制返回结果的数量。即使范围内有100个地点,COUNT 5 也只会返回5个。

        注意: 如果不指定排序,COUNT 的行为在 Redis 7.0 前后有变化。在 7.0 中,默认不应用任何限制,除非显式指定。为安全起见,最好与 ASC/DESC 联用。

        • ASC

          将结果按距离从近到远排序。

        • DESC

          将结果按距离从远到近排序。

bash 复制代码
127.0.0.1:6379> geosearch people frommember p1 byradius 5000 km asc count 3 withdist
1) 1) "p1"
   2) "0.0000"
2) 1) "p4"
   2) "2659.7315"
3) 1) "p3"
   2) "3958.1901"

三、内部实现

Geospatial 的内部实现巧妙地利用了 Sorted SetGeohash 算法。

  1. 数据结构

    • 当你使用 GEOADD 添加一个地理位置时,Redis 会将其存储在一个 Sorted Set 中。
    • Sorted Set 的 member: 就是你添加的地理位置名称(如 "Beijing")。
    • Sorted Set 的 score : 是一个 52 位的整数,这个整数是由 Geohash 算法计算出来的。
  2. Geohash 算法

    • Geohash 的核心思想是将地球表面递归地划分为网格,并为每个网格分配一个唯一的编码。
    • 算法将经纬度坐标转换成一个 Base32 编码的字符串。Redis 内部将这个字符串转换成一个 52 位的整数值作为 Sorted Set 的分数(score)。

四、应用场景

  1. 附近的人 / 附近的商家

    • 这是最典型的应用。在社交、外卖、团购等 App 中,这是核心功能。
    • 实现 : 将用户/商家的坐标 GEOADD 到集合中。当用户想查找附近的人或商家时,使用 GEOSEARCH ... FROMMEMBER ... BYRADIUS ... 命令即可快速获取列表。
  2. 共享单车 / 网约车

    • 用于查找用户附近的空闲单车或车辆。
    • 实现: 实时更新所有单车的位置到 Redis 中。用户打开 App 时,直接查询用户所在位置半径内的所有单车。
  3. 地理位置围栏

    • 判断一个点(如车辆、快递员)是否进入或离开某个特定区域。
    • 实现 : 可以定期将设备的坐标与预设的围栏区域(使用 GEOSEARCH ... BYBOX ...)进行比对,如果发现设备出现在围栏内,则触发相应操作。
  4. 物流与配送路径优化

    • 虽然复杂的路径规划需要专门的 GIS 系统,但 Redis GEO 可以快速筛选出配送点附近的仓库或中转站,作为路径规划的初步输入。
  5. 旅行规划

    • 在某个旅游城市,查找景点附近的所有酒店或餐厅。
相关推荐
hhh小张2 小时前
Redis基本数据类型:Sorted Set (ZSet)
redis
hhh小张2 小时前
Redis特殊数据类型:Bitmap
redis
召摇4 小时前
Redis与PostgreSQL缓存性能终极对决:7千次/秒真的够用吗?
redis·postgresql·面试
帧栈5 小时前
开发避坑指南(61):Redis持久化失败:RDB快照因磁盘问题无法保存解决方案
数据库·redis·缓存
晨港飞燕6 小时前
Websocket+Redis实现微服务消息实时同步
redis·websocket·微服务
gsfl6 小时前
redis单线程模型
数据库·redis·缓存
hhh小张10 小时前
Redis基本数据类型:Hash
redis
Vahala0623-孔勇11 小时前
分布式锁巅峰对决:Redis RedLock vs ZooKeeper临时节点——Redission看门狗如何破解续期困局
redis·分布式·zookeeper
gsfl12 小时前
Redis List 类型全解析
数据库·redis·list