*Redis BITPOS 命令
BITPOS 返回字符串中第一个被设置为 1(或 0)的位的位置,可指定字节范围搜索。
*语法
BITPOS key bit [start [end [BIT | BYTE]]]
*参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| key | String | 是 | 键名 |
| bit | Integer (0/1) | 是 | 查找的位值(0 或 1) |
| start | Integer | 否 | 起始位置(0-based) |
| end | Integer | 否 | 结束位置(0-based,包含) |
| BIT / BYTE | Keyword | 否 | 指定 start/end 的单位,默认 BYTE。Redis 7.0+ 支持 BIT 单位 |
*返回值
- Integer:第一个匹配位的位置(0-based)
- 查找 1 时:没找到返回 -1
- 查找 0 时:没找到返回字符串总位数(因为所有位都是 1)
*时间复杂度
O(N),N 为扫描的字节数或位数
*示例
*查找第一个 1
> SET mykey "\x00\xff\x00"
OK
> BITPOS mykey 1
8
*查找第一个 0
> SET mykey "\xff\xff\x00"
OK
> BITPOS mykey 0
16
*按字节范围查找(只在第 1~2 字节中找)
> SET mykey "\x00\x01\x00"
OK
> BITPOS mykey 1 1 2
15
*按位范围查找(Redis 7.0+)
> BITPOS mykey 1 8 15 BIT
15
*常见错误
| 错误 | 原因 | 解决 |
|---|---|---|
| WRONGTYPE | key 不是 String 类型 | 检查 key 类型 |
| ERR bit must be 0 or 1 | bit 参数不是 0 或 1 | 传入 0 或 1 |
*最佳实践
- 位图查询利器:快速定位第一个满足条件的位
- 找 0 的特殊语义:没找到时返回字符串总长度,可借此判断字符串是否全为 1
- 大数据量时指定 start/end 缩小扫描范围
- 配合 BITCOUNT 使用:BITPOS 找位置,BITCOUNT 统计数量
- 位图全为空(全 0)时,BITPOS key 1 返回 -1
*FAQ
Q1: BITPOS 返回 -1 是什么意思? A: 查找 1 时没找到,即整个字符串全是 0。
Q2: 查找 0 没找到时为什么返回字符串长度而不是 -1? A: 这是 Redis 的设计语义。全为 1 的字符串中,"第一个 0" 的位置被定义为字符串末尾之后(等于总位数),便于区分"全 1"和"没找到"。
Q3: BITPOS 和 GETBIT 有什么区别? A: GETBIT 查询指定位的值;BITPOS 搜索第一个满足条件的位,不知道位置时使用。