当前位置: 首页 > news >正文

Redis GEO 地理位置搜索:实战示例 + 底层原理解析

📝 文章概要

Redis 不仅是高性能的键值数据库,还内置了地理位置(GEO)功能,支持存储经纬度并快速查询附近的地点。本篇文章将通过示例讲解如何在 Redis 5.x 中使用 GEO 命令进行地理位置存储与范围搜索,并解析其底层实现原理,让你不仅会用,还能理解背后的机制。

📝 文章内容

1️⃣ Redis GEO 简介

Redis GEO 命令允许我们:

  • 存储带经纬度的地理位置

  • 查询某个点附近的对象(半径范围)

  • 计算两点距离

  • 获取位置坐标

GEO 命令适用于 Redis 5.x:GEOADDGEORADIUSGEORADIUSBYMEMBERGEODISTGEOPOSGEOHASH


2️⃣ GEO 命令示例

2.1 添加城市地理位置
# 创建 key 为 city_geo 的地理数据集合
GEOADD city_geo 116.403963 39.915119 "北京·天安门"
GEOADD city_geo 121.473701 31.230416 "上海·外滩"
GEOADD city_geo 113.264385 23.129112 "广州·天河"
GEOADD city_geo 114.057868 22.543099 "深圳·福田"
GEOADD city_geo 104.066541 30.572269 "成都·天府广场"
GEOADD city_geo 117.200983 39.084158 "天津·鼓楼"
GEOADD city_geo 118.796877 32.060255 "南京·新街口"
GEOADD city_geo 120.155070 30.274084 "杭州·西湖"
GEOADD city_geo 106.551556 29.563009 "重庆·解放碑"
GEOADD city_geo 87.616848 43.825592 "乌鲁木齐·市政府"
GEOADD city_geo 108.940174 34.341568 "西安·钟楼"
GEOADD city_geo 126.534967 45.803775 "哈尔滨·中央大街"
GEOADD city_geo 91.132212 29.660361 "拉萨·布达拉宫"
GEOADD city_geo 114.305393 30.593099 "武汉·江汉路"
GEOADD city_geo 113.625368 34.746599 "郑州·二七塔"

2.2 查询某城市周边范围

# 按成员查找
GEORADIUSBYMEMBER city_geo "上海·外滩" 500 km WITHDIST WITHCOORD ASC# 按坐标查找
GEORADIUS city_geo 114.057868 22.543099 300 km WITHDIST WITHCOORD ASC
2.3 计算城市间距离
GEODIST city_geo "北京·天安门" "上海·外滩" km
2.4 获取城市经纬度
GEOPOS city_geo "广州·天河"

3️⃣ GEO 存储原理解析

3.1 底层是有序集合 ZSET
  • GEOADD 实际上就是把地理坐标转换为 52 位整数 geohash,然后存入 ZSET 的 score。

  • 通过 ZSET 的有序特性,Redis 可以快速查找范围内的元素。

3.2 为什么看不到经纬度?
  • 在 ZSET 内,成员名称保留原名

  • score 是压缩后的 geohash 编码

  • 使用 GEOPOS 可以反解出原始经纬度

3.3 搜索流程
  1. 将查询中心点经纬度编码为 geohash

  2. 计算半径对应的 geohash 区块

  3. ZSET 范围扫描,获取可能的候选点

  4. 精确计算球面距离,过滤出最终结果


4️⃣ 示例:Java Jedis 使用 GEO

Jedis jedis = new Jedis("localhost", 6379);
jedis.geoadd("city_geo", 116.403963, 39.915119, "北京·天安门");
jedis.geoadd("city_geo", 121.473701, 31.230416, "上海·外滩");List<GeoRadiusResponse> results = jedis.georadiusByMember("city_geo","北京·天安门",1500,GeoUnit.KM,GeoRadiusParam.geoRadiusParam().withCoord().withDist().sortAscending()
);for (GeoRadiusResponse r : results) {System.out.println(r.getMemberByString() + " 距离: " + r.getDistance() + "km");
}

5️⃣ 总结

  • Redis GEO 命令在 Redis 5.x 版本中依赖 ZSET 存储

  • 数据虽然存入 ZSET,但可以通过命令获取精确经纬度

  • 非常适合附近搜索、位置服务等场景

  • 理解底层原理,有助于做性能优化与大数据量处理

http://www.dtcms.com/a/536231.html

相关文章:

  • Java的中间件
  • 邢台学校网站建设价格百度企业服务平台
  • 建网站要注意的细节物流网站首页图片
  • 牙根尖挺使用失误的常见原因分析及规避方法
  • 麒光AI-OCT大模型:心血管诊疗的智能革命与未来展望
  • AI 驱动的 ITSM:数字化转型时代的 IT 服务新范式
  • EasyGBS视频实时监控系助力实现换热站全景可视化管理
  • HarmonyOS安全加密与TEE开发实战
  • 门户网站建设 简报网络培训视频如何加速
  • uniapp引入uniim后聊天列表无法加载出来
  • AWS Auto Scaling:自动扩容,让服务器像呼吸一样灵活
  • 实战|AWS Snowcone边缘计算落地工业场景:从技术原理到代码实现
  • uni-app facebook登录
  • 【设计模式笔记07】:迪米特法则
  • SIP协议详解:从请求到挂断的全生命周期
  • 药材网网站技术建设手机网站微信链接怎么做
  • 【Linux】 第一个系统程序——进度条
  • 旅游seo整站优化宁波做网站有哪些公司公司
  • CircleCI 让持续集成变得简单而高效的开源框架
  • Ribbon是如何与服务注册中心nacos交互的
  • 自然语言处理框架:Bert和Transformer
  • (N_157)基于springboot,vue服装商城系统
  • 介绍一下Ribbon
  • 潍坊有哪些网站旅行社网站规划与建设的流程图
  • (项目管理系列课程)项目规划阶段:项目进度管理-估算活动持续时间
  • STM32定时器的输入捕获模式(测量PWM的周期与占空比)
  • 智慧校园数字孪生选型指南:选对平台做好交付,从平台适配到交付落地的全流程解决方案
  • php招生网站开发标准网站建设价格
  • 【NestJS】在 nest.js 项目中,如何使用 Postgresql 来做缓存?
  • 解决由于没有远程桌面授权服务器可以提供许可证,远程会话被中断.的方法