Redis 怎么查询附近门店并按距离排序
如果门店已经有经度和纬度,Redis 不需要把每条门店记录都取到应用层再计算距离。先用 GEOADD 把门店成员写入同一个地理索引,再用 GEOSEARCH 指定中心点、半径和 ASC,就能得到“附近门店 + 最近优先”的结果。接口通常再加上 WITHDIST 返回距离,前端便可以直接展示“1.8 km”。
最小可用写法是:GEOSEARCH store:geo FROMLONLAT 121.4737 31.2304 BYRADIUS 5 KM ASC WITHDIST COUNT 10。其中经度在前、纬度在后,ASC表示由近到远。
GEOADD的参数顺序是 longitude、latitude、member,地理数据保存在有序集合中。GEOSEARCH支持FROMLONLAT或已有成员作为中心,圆形范围用BYRADIUS。- 要展示距离使用
WITHDIST;生产接口可用COUNT限制返回量,但不要随意加ANY。
GEOADD 先把门店放进地理索引
Redis 的 GEO 数据以 sorted set 形式存储,门店名称是 member,经纬度被编码进 score。业务上可以把 key 命名为 store:geo,再把门店的其他信息放在普通 Hash 或数据库里;地理索引负责“谁在附近”,详情查询负责“门店有哪些字段”。
# 经度在前,纬度在后;每组三个参数对应一个门店 redis-cli GEOADD store:geo \ 121.4737 31.2304 store-a \ 121.4800 31.2280 store-b \ 121.4652 31.2351 store-c # 查看一个成员的坐标,检查写入顺序是否正确 redis-cli GEOPOS store:geo store-a
示例中的 store-a 只是索引成员,不等同于完整门店对象。更新门店位置时再次执行 GEOADD 会更新已有成员的坐标;删除门店则使用 ZREM store:geo store-a。这种拆分能避免为了更新地址而重写一整份门店详情。

用 GEOSEARCH 按半径筛选并按距离排序
查询坐标附近门店时,使用 FROMLONLAT 传入用户当前位置,BYRADIUS 传入半径和单位,再加 ASC。下面以 5 公里为范围,最多取 10 家,并返回距离:
# 以用户坐标为中心,在 5 KM 内由近到远取 10 家门店 redis-cli GEOSEARCH store:geo \ FROMLONLAT 121.4737 31.2304 \ BYRADIUS 5 KM ASC COUNT 10 WITHDIST # 需要把坐标也交给地图卡片时,再追加 WITHCOORD redis-cli GEOSEARCH store:geo \ FROMLONLAT 121.4737 31.2304 \ BYRADIUS 5 KM ASC COUNT 10 WITHDIST WITHCOORD
第一条命令只返回成员名和距离,第二条还会返回每个成员的经纬度。ASC 是按离中心点的距离升序排列,省略排序选项时不要把返回顺序当成最近优先。若查询中心本身就是某个已索引门店,也可以把 FROMLONLAT 换成 FROMMEMBER store-a。
| 查询片段 | 作用 | 接口选择建议 |
|---|---|---|
FROMLONLAT lon lat | 使用请求中的坐标作为中心 | 用户定位、配送点、临时坐标 |
BYRADIUS 5 KM | 限定圆形范围和单位 | “附近 5 公里”这类需求 |
ASC | 最近的成员排在前面 | 列表按距离展示 |
WITHDIST | 返回距离数值 | 展示距离或二次业务判断 |

读取距离和坐标时要看清返回形状
不带任何 WITH* 选项时,结果只是成员名数组;带 WITHDIST 或 WITHCOORD 后,每个成员会变成一个子数组。距离单位跟 BYRADIUS 使用的单位一致,因此命令里写 KM,应用层就按公里解释,不必再把数值乘除一遍。
package main
import "fmt"
// 解析 GEOSEARCH 的成员、距离和坐标,避免把距离当成米
type NearbyStore struct {
ID string
Distance float64 // 单位由查询中的 KM 或 M 决定
Longitude float64
Latitude float64
}
// 生产代码应按客户端库的 GeoLocation 结构读取,先明确统一单位
func displayDistance(distance float64, unit string) string {
// 这里只格式化查询返回值,不重新计算球面距离
return fmt.Sprintf("%.1f %s", distance, unit)
}
如果业务还要显示营业状态、门店名称或库存,建议先拿到成员 ID,再批量读取 Hash 或数据库记录。地理查询只解决空间范围和距离排序,不会自动把外部门店详情拼接进结果。
COUNT、ANY 和经纬度顺序的常见坑
COUNT 10 表示最多返回 10 个匹配成员,但服务器仍需要在范围内处理并排序。官方文档特别说明,范围很大而 COUNT 很小时,排序工作仍可能明显;ANY 会在找到足够数量后提前结束,速度可能更快,但结果可能不是有序的。需要“最近的 10 家”时,不要为了少一次计算就加 ANY。
另外,Redis 使用标准的 x、y 顺序,即经度在前、纬度在后。经度合法范围为 -180 到 180,纬度可索引范围约为 -85.05112878 到 85.05112878。把国内常见的“纬度、经度”接口字段直接传给 GEOADD,通常不会报语法错误,却会把门店放到错误位置。写入前最好在应用层统一字段名,例如 longitude 和 latitude,并对边界值做一次业务校验。
最后,半径查询适合“附近”筛选,不等于驾车路线距离。若页面要展示预计到店时间或真实道路距离,还需要调用地图路线服务;Redis 返回的是基于地理坐标的直线距离。
常见问题
GEOSEARCH 和 GEORADIUS 应该选哪个?
新代码优先使用 GEOSEARCH。它能覆盖圆形和矩形范围,Redis 文档将 GEORADIUS 与 GEORADIUSBYMEMBER 标为弃用方向。
为什么查出来的距离不是整数?
距离是浮点数,Redis 会按查询单位返回带小数的结果。展示层可以保留一位小数,但不要把小数直接当作精确的道路里程。
能不能用门店名称作为查询中心?
可以,只要该成员已经在同一个地理 key 中,使用 FROMMEMBER member;如果中心来自用户定位,则使用 FROMLONLAT。
Go POST 请求重定向后为什么变成 GET
- 上一篇
- Go POST 请求重定向后为什么变成 GET
- 下一篇
- Go 中文字符串怎么按字符截取而不产生乱码
-
- 数据库 · Redis | 2小时前 |
- Redis 统计 UV 怎么用 HyperLogLog:误差和适用场景
- 302浏览 收藏
-
- 数据库 · Redis | 3小时前 | Redis · ZSET · 排行榜 · zset Redis排行榜 Sorted Set
- Redis 排行榜分数相同时怎么安排排序
- 279浏览 收藏
-
- 数据库 · Redis | 1天前 |
- Redis Stream 消费者挂掉后消息卡在 PEL:用 XAUTOCLAIM 做可重复的接管流程
- 345浏览 收藏
-
- 数据库 · Redis | 1天前 |
- Redis Lua 长脚本怎么拆:保留短状态变更并控制单次批量
- 216浏览 收藏
-
- 数据库 · Redis | 1天前 | 消息队列 · Redis教程 · 故障恢复 · 消费组 · redis 消费组 Redis Streams XNACK Pending 消息
- Redis XNACK 如何快速交回 Pending 消息:消费者退出与重投优先级
- 332浏览 收藏
-
- 数据库 · Redis | 2天前 | Redis · 性能 · 集合 · 数据统计 · 基数统计 Redis 8.10 SUNIONCARD 集合并集
- Redis 8.10 SUNIONCARD 为什么不返回成员:集合并集计数的低开销用法
- 490浏览 收藏
-
- 数据库 · Redis | 2天前 | Redis · 队列 · 列表命令 · Redis列表 Redis 8.10 BLMOVEM LMOVEM
- Redis 8.10 LMOVEM 与 BLMOVEM 怎么选:一次移动多元素的队列边界
- 278浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 155次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 85次使用
-
- ClickPrompt
- ClickPrompt是一款专为AI提示词编写者设计的开源在线工具,支持Stable Diffusion绘图、ChatGPT对话及GitHub Copilot代码辅助。提供Prompt自动生成、一键运行、社区分享及可视化优化功能,帮助用户高效获取精准AI输出。
- 45次使用
-
- PromptHero
- PromptHero是专业的AI提示词搜索引擎与优化平台,支持Stable Diffusion、Midjourney等主流模型。提供海量提示词库、分类搜索、在线课程及社区互动,助力用户高效生成高质量AI图像与文本。
- 25次使用
-
- Stable Diffusion Prompt Book
- 深入解析OpenArt推出的Stable Diffusion Prompt Book,这本免费的开源提示词指南涵盖从基础语法到高级技巧,提供风格化词库与参数建议,助您优化AI绘画生成效果。
- 28次使用
-
- Go与Redis实现分布式互斥锁和红锁
- 2022-12-22 117浏览
-
- Go+Redis实现延迟队列实操
- 2023-02-23 426浏览
-
- 一文搞懂Go语言操作Redis的方法
- 2023-01-07 171浏览
-
- Golang分布式应用之Redis示例详解
- 2023-01-07 113浏览
-
- Go Redis客户端使用的两种对比
- 2022-12-30 195浏览

