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. 旅行规划

    • 在某个旅游城市,查找景点附近的所有酒店或餐厅。
相关推荐
雪域迷影6 分钟前
Windows11上安装Redis服务和Redis可视化客户端
windows·redis
青云交12 分钟前
Java 大视界 -- 基于 Java+Redis Cluster 构建分布式缓存系统:实战与一致性保障(444)
java·redis·缓存·缓存穿透·分布式缓存·一致性保障·java+redis clus
三不原则31 分钟前
故障案例:模型推理响应慢,排查 Redis 缓存集群问题
数据库·redis·缓存
小北方城市网13 小时前
分布式锁实战指南:从选型到落地,避开 90% 的坑
java·数据库·redis·分布式·python·缓存
ohoy14 小时前
RedisTemplate 使用之Zset
java·开发语言·redis
冰冰菜的扣jio17 小时前
Redis缓存中三大问题——穿透、击穿、雪崩
java·redis·缓存
阿里巴巴P8资深技术专家18 小时前
基于 Spring AI 和 Redis 向量库的智能对话系统实践
人工智能·redis·spring
oMcLin18 小时前
如何在 AlmaLinux 9 上配置并优化 Redis 集群,支持高并发的实时数据缓存与快速查询?
数据库·redis·缓存
洛阳纸贵19 小时前
Redis
数据库·redis·缓存
挺6的还20 小时前
13.持久化
redis