*Redis GEORADIUSBYMEMBER 命令
GEORADIUSBYMEMBER 以指定成员的位置为中心点,搜索给定半径范围内的所有地理空间成员,并返回符合条件的成员列表。
*语法
GEORADIUSBYMEMBER key member radius <M | KM | FT | MI> [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count [ANY]] [ASC | DESC] [STORE key] [STOREDIST key]
*参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| key | String | 是 | 存储地理空间数据的键名 |
| member | String | 是 | 中心点的成员名称,命令以此成员的位置为圆心 |
| radius | Double | 是 | 搜索半径 |
| M / KM / FT / MI | Enum | 是 | 半径单位:米、千米、英尺、英里 |
| WITHCOORD | Flag | 否 | 返回结果中包含成员的经纬度坐标 |
| WITHDIST | Flag | 否 | 返回结果中包含成员到中心点的距离 |
| WITHHASH | Flag | 否 | 返回结果中包含成员的 Geohash 原始 52 位整数值 |
| COUNT count | Integer | 否 | 限制返回结果的数量 |
| ANY | Flag | 否 | 与 COUNT 配合使用时,只要找到足够数量的结果就立即返回,不保证距离最近 |
| ASC / DESC | Enum | 否 | 按距离升序(ASC)或降序(DESC)排列 |
| STORE key | String | 否 | 将结果存储到指定键中(作为有序集合) |
| STOREDIST key | String | 否 | 将结果存储到指定键中,分数为距离值 |
*返回值
- Array:默认返回符合条件的成员名称数组
- Array of arrays:使用 WITHCOORD / WITHDIST / WITHHASH 时,返回包含多个字段的数组结构
- Nil:键不存在或成员不存在时返回空数组
- Error:键不是 geo 类型、成员不存在、单位非法等
*时间复杂度
O(N + log M),其中 N 是半径范围内的元素数量,M 是有序集合中的元素总数。
*示例
*基本用法
> GEOADD cities 116.4074 39.9042 "beijing" 121.4737 31.2304 "shanghai" 113.2644 23.1291 "guangzhou"
(integer) 3
> GEORADIUSBYMEMBER cities "beijing" 1000 KM
1) "beijing"
2) "shanghai"
*返回距离和坐标
> GEORADIUSBYMEMBER cities "beijing" 1500 KM WITHDIST WITHCOORD
1) 1) "beijing"
2) "0.0000"
3) 1) "116.40739494514465332"
2) "39.90421156550293564"
2) 1) "shanghai"
2) "1067.7397"
3) 1) "121.47370290756225586"
2) "31.23039561503564217"
*限制返回数量并排序
> GEORADIUSBYMEMBER cities "beijing" 2000 KM COUNT 2 ASC WITHDIST
1) 1) "beijing"
2) "0.0000"
2) 1) "shanghai"
2) "1067.7397"
*常见错误
| 错误 | 原因 | 解决 |
|---|---|---|
| ERR could not decode requested zset member | 指定的中心成员不存在 | 确认成员名称拼写正确,或先用 GEOADD 添加 |
| ERR wrong number of arguments | 缺少必填参数 | 至少提供 key, member, radius, unit |
| ERR unsupported unit provided. please use M, KM, FT, MI | 单位参数错误 | 使用 M、KM、FT 或 MI |
| WRONGTYPE Operation against a key holding the wrong kind of value | key 不是 geo 类型 | 检查 key 的数据类型 |
*最佳实践
- 大数据集优化:使用 COUNT 限制返回数量,配合 ASC 优先获取最近的结果,避免 O(N) 的全量返回
- 结果缓存:频繁查询的场景可使用 STORE / STOREDIST 将结果存储到新 key 中复用
- 距离精度:GEORADIUSBYMEMBER 使用 geohash 网格近似计算,结果存在约 0.5% 的误差,对精度要求极高的场景需二次校验
- ANY 选项:在允许近似结果的场景下,使用
COUNT N ANY可显著降低 CPU 消耗,因为一旦找到 N 个结果就立即返回,无需全局排序
*FAQ
Q1: GEORADIUSBYMEMBER 和 GEORADIUS 有什么区别? A: GEORADIUS 需要直接提供中心点的经纬度坐标;GEORADIUSBYMEMBER 则以有序集合中某个已有成员的位置为圆心。当中心点本身就是数据集中的成员时,使用 GEORADIUSBYMEMBER 更方便。
Q2: WITHHASH 返回的是什么? A: 返回的是 Redis 内部存储的 52 位 Geohash 原始整数值,可用于调试或与其他系统对接。对人类阅读不友好,通常不需要使用。
Q3: COUNT 和 ANY 配合使用有什么注意事项?
A: COUNT N ANY 表示只要找到 N 个结果就立即返回,不保证这 N 个是距离最近的。适用于"附近找任意 N 个"的场景,可大幅提升性能。如果需要最近的 N 个,不要使用 ANY。
Q4: GEORADIUSBYMEMBER 的搜索精度如何? A: 基于 geohash 网格计算,边缘有约 0.5% 的误差。半径越大,误差绝对值越大。需要精确几何计算的场景应使用 Haversine 公式在后端二次过滤。