GEOADD命令需严格遵循“key 经度 纬度 成员名”顺序,经度在前(-180~180)、纬度在后(-90~90),坐标须为字符串数字,成员名用业务唯一ID;错误示例包括参数倒置、科学计数法、空格key、单位缺失等。

GeoADD 命令怎么写才不会报错
直接用 GEOADD 录入商铺坐标,最常踩的坑是参数顺序反了、经纬度类型错了、或者 key 名带空格。Redis 的 Geo 坐标要求是「经度在前、纬度在后」,和日常说“北纬东经”习惯相反;而且必须是字符串数字,不能是科学计数法或 NaN。
-
GEOADD后第一个参数是key(比如shop:location),不是坐标 - 后续必须成对出现:一个经度 + 一个纬度 + 一个成员名(如商铺 ID
shop:1001) - 经度范围是 -180 到 180,纬度是 -90 到 90;超出会报错
(error) ERR invalid longitude, latitude - 成员名建议用业务唯一 ID,别用中文或空格,否则后续
GEORADIUS查起来容易漏转义
示例:GEOADD shop:location 116.4810 39.9963 shop:1001 —— 这才是北京某店的正确写法。
为什么用 GEOADD 而不用普通 HASH 存经纬度
单纯存 lat/lng 字段到 HASH 里,后续做“5 公里内商铺”这种查询就得全量扫、自己算球面距离,慢且不准。而 GEOADD 底层把坐标转成 geohash 并建索引,GEORADIUS 或 GEORADIUSBYMEMBER 才能真正 O(log N) 定位。
- Redis Geo 不是“存储方案”,而是“地理索引方案”;它不关心你存的是商铺、充电桩还是骑手,只负责快速圈出范围
- 每个
key对应一个地理集合,同一个 key 下可存上万点,但不要混不同业务类型(比如把用户和商铺塞进同一个shop:location) - 注意:Redis Geo 只支持 WGS84 坐标系,如果你的数据来自高德或百度地图(GCJ-02 或 BD-09),得先纠偏,否则位置偏差几百米
批量导入时 GEOADD 性能卡在哪
单条 GEOADD 没问题,但循环发几千次命令会明显变慢——主要卡在网络往返和 Redis 单线程串行执行上,不是命令本身慢。
- 改用 pipeline:把多组坐标拼成一个请求,例如
GEOADD shop:location 116.4810 39.9963 shop:1001 116.4820 39.9970 shop:1002 - 一次最多塞 100–200 个点,再多可能触发客户端缓冲区限制或 Redis 单命令长度限制(默认 512MB,但实际建议控制在几 MB 内)
- 如果从 CSV 导入,别用 shell 脚本一行行
redis-cli -x,改用 Python 的redis-py+pipeline.execute(),吞吐能提 5–10 倍
录入后查不到?检查这三处硬性限制
明明 GEOADD 返回 1,GEORADIUS 却返回空数组,大概率掉进了这三个隐形坑里:
- 坐标精度丢失:前端传来的经纬度被 JS 浮点数截断(如
116.48099999999999),Redis 存的时候四舍五入到小数点后 7 位,查的时候用原始值就匹配不上 —— 统一保留 6 位小数再入库 - 单位混淆:
GEORADIUS的距离参数单位必须显式指定,m(米)、km、mi、ft缺一不可,写500不加单位就是语法错误 - key 名大小写/冒号不一致:存的时候用
Shop:Location,查的时候用shop:location,Redis 当两个 key 看 —— 建议全部小写 + 英文冒号,写死在配置里
真要 debug,先用 GEOPOS shop:location shop:1001 看存进去的坐标是否和预期一致,比瞎猜快得多。










