*Redis CF.INSERTNX 命令

CF.INSERTNX 将一个或多个元素添加到 Cuckoo Filter 中,仅当元素之前不存在时才插入。如果过滤器不存在则自动创建。


*语法

CF.INSERTNX key [CAPACITY capacity] [NOCREATE] ITEMS item [item ...]

*参数说明

参数 类型 必填 说明
key String Cuckoo Filter 的键名
CAPACITY capacity Integer 新过滤器的期望容量(仅在过滤器不存在时生效)
NOCREATE Flag 禁止自动创建过滤器,如果键不存在则返回错误
ITEMS item... String / Bytes 要插入的一个或多个元素

*返回值

返回一个整数数组,每个元素对应一个插入操作的结果:

  • 1:元素成功插入(之前不存在)
  • 0:元素的指纹已存在于过滤器中(未插入)
  • -1:无法插入,因为过滤器已满

特殊情况: - Simple error reply:参数数量或类型错误,或者指定了 NOCREATE 但键不存在时返回


*时间复杂度

O(n * (k + i)),其中 n 是元素数量,k 是子过滤器数量,i 是 maxIterations。


*示例

*基本用法(首次插入)

> CF.INSERTNX cf CAPACITY 1000 ITEMS item1 item2
1) (integer) 1
2) (integer) 1

*重复插入(元素已存在)

> CF.INSERTNX cf CAPACITY 1000 ITEMS item1 item2 item3
1) (integer) 0
2) (integer) 0
3) (integer) 1

*禁止自动创建

> CF.INSERTNX cf_new CAPACITY 1000 NOCREATE ITEMS item1 item2
(error) ERR not found

*批量插入并检查重复

> CF.INSERTNX cf_dedup ITEMS a b c d
1) (integer) 1
2) (integer) 1
3) (integer) 1
4) (integer) 1
> CF.INSERTNX cf_dedup ITEMS c d e f
1) (integer) 0
2) (integer) 0
3) (integer) 1
4) (integer) 1

*常见错误

错误 原因 解决
ERR wrong number of arguments 参数数量不足 检查是否提供了 ITEMS 和至少一个元素
ERR not found 指定了 NOCREATE 但键不存在 先使用 CF.RESERVE 创建过滤器,或移除 NOCREATE 选项
ERR item exists 键已存在但不是 Cuckoo Filter 类型 使用不同的键名,或删除现有键

*最佳实践

  • 去重场景:CF.INSERTNX 适合需要去重判断的场景,例如防止重复处理任务、唯一性约束等
  • 注意假阳性:由于 CF.EXISTS 可能存在假阳性(false positive),CF.INSERTNX 可能因误判元素已存在而拒绝插入。如果对假阳性敏感,建议结合其他数据结构二次确认
  • 性能考虑:CF.INSERTNX 比 CF.INSERT 慢,因为每个元素插入前都需要先检查是否存在。如果不需要去重判断,优先使用 CF.INSERT
  • CAPACITY 与 NOCREATE 互斥:这两个选项不能同时使用
  • 批量操作:尽量一次插入多个元素,减少网络往返开销

*FAQ

Q1: CF.INSERTNX 和 CF.INSERT 有什么区别? A: CF.INSERTNX 在插入前会先检查元素是否已存在,如果存在则跳过插入并返回 0。CF.INSERT 无条件插入。CF.INSERTNX 适合去重场景,但性能稍差。

Q2: 返回 0 表示元素一定存在吗? A: 不一定。由于 Cuckoo Filter 的假阳性特性,CF.INSERTNX 可能误判元素已存在而返回 0,实际上该元素可能并未被插入过。如果需要 100% 准确的去重判断,建议配合其他数据结构(如 Redis Set)使用。

Q3: 为什么 CF.INSERTNX 比 CF.INSERT 慢? A: CF.INSERTNX 对每个元素都需要先执行 CF.EXISTS 检查(O(k + i) 复杂度),然后再决定是否插入。而 CF.INSERT 直接尝试插入。因此 CF.INSERTNX 的时间复杂度大约是 CF.INSERT 的两倍。

Q4: 如果过滤器已满,CF.INSERTNX 会返回什么? A: 会返回 -1,表示无法插入该元素。这与 CF.INSERT 的行为一致。需要注意的是,即使元素确实不存在(在另一个数据结构中确认),如果过滤器已满也无法插入。