GEO 是什么
Redis 的地理检索建立在 ZSet 之上:经纬度先被编码成 52 位整数(GeoHash),这个整数就是 ZSet 的分数,因此「按距离找附近」在实现上等价于「在分数接近的区间里取成员」。GEOADD 负责写入,GEOSEARCH 按圆形或矩形范围查询并能返回距离、按距离排序,GEODIST 计算两点间距离,GEOPOS 反查坐标。因为底层就是 ZSet,GEO 键也可以用 ZREM、ZCARD 等命令操作。
基本信息
| 写入 | GEOADD key 经度 纬度 成员名,坐标顺序为经度在前 |
|---|---|
| 范围查询 | GEOSEARCH key FROMLONLAT lon lat BYRADIUS 100 km ASC |
| 距离计算 | GEODIST key member1 member2 km,单位可为 m/km/mi/ft |
| 反查坐标 | GEOPOS key member,返回经纬度 |
| 废弃命令 | GEORADIUS 与 GEORADIUSBYMEMBER 自 6.2 起标记为废弃,新代码用 GEOSEARCH |
典型使用场景
- 附近的门店或服务点:给定用户坐标找半径内的对象,并按距离排序返回最近几家
- 配送范围判断:判断骑手或车辆是否落在某个商圈范围内
- 同城内容推荐:按距离阈值筛选候选对象,再交给业务排序
- 仓库与自提点匹配:按用户位置找出最近的若干自提点
- 轨迹点存储:把设备位置按时间片写入 GEO 键,用于最近位置查询
写入与查询
写入与查询
redis-cli GEOADD cities 116.4074 39.9042 beijing 121.4737 31.2304 shanghai
redis-cli GEOSEARCH cities FROMLONLAT 116.4074 39.9042 BYRADIUS 1200 km WITHDIST ASC
redis-cli GEOSEARCH cities FROMMEMBER beijing BYRADIUS 500 km COUNT 10 # 以已有成员为中心
redis-cli GEOSEARCH cities FROMLONLAT 116.4 39.9 BYBOX 100 100 km ASC # 矩形范围
redis-cli GEODIST cities beijing shanghai km # 两点直线距离
redis-cli GEOPOS cities beijing # 反查坐标
redis-cli ZCARD cities # 底层就是 ZSet,可当普通集合统计常用参数
| 参数 | 含义 | 说明 |
|---|---|---|
| FROMLONLAT | 以给定经纬度为中心 | 经纬度顺序不能颠倒 |
| FROMMEMBER | 以已有成员的位置为中心 | 成员不存在时返回空结果 |
| BYRADIUS | 圆形范围,需带单位 | m / km / mi / ft |
| BYBOX | 矩形范围,宽高加单位 | 适合按街区或网格筛选 |
| WITHDIST / ASC | 返回距离并按距离升序 | 取最近 N 个的常规组合 |
距离是直线距离而非路网距离:GEO 计算的是两点间的地理直线,实际驾车或步行距离需要另行计算。用于「附近 3 公里」这类业务时,通常先把半径适当放大作为候选集,再用第三方路网服务精算。
经纬度顺序写反不会报错但结果完全错误:GEOADD 的语法是「经度 纬度」,经度范围约在负 180 到 180 之间,纬度在负 85 到 85 之间。如果纬度值超过 85 会因越界而报错,但两个都在范围内时错误会静默产生。