当前位置: 首页 > news >正文

RedisJSON 指令精讲JSON.TOGGLE 键翻转布尔值

1 · 为什么要学 JSON.TOGGLE?

在特性开关、状态机、AB 实验、勾选框等场景下,我们经常需要把 truefalse 来回切换。传统做法要先 JSON.GET 读出布尔值、在客户端翻转、再 JSON.SET 写回;这不仅多一次 RTT,还增加竞态风险。JSON.TOGGLE 直接在 Redis 端 原子翻转 布尔字段,让代码更简洁、操作更安全。

2 · 指令概览

指令作用复杂度
JSON.TOGGLE key [path]将指定路径布尔值取反O(1)(单路径) / O(N)(多路径,与键大小相关)
  • 可用版本:RedisJSON ≥ 2.0.0
  • ACL 标签@json @write @slow
  • 默认路径$(根)

3 · 语法解析

JSON.TOGGLE <key> [<path>]
参数必填说明
key目标键名
pathJSONPath,省略时为 $

返回值

  • 布尔 → 数字:翻转后值,1 代表 true0 代表 false
  • 多路径:数组形式,顺序与匹配点一致
  • 非布尔:返回 nil
  • 路径不存在:同样返回 nil

4 · 实战示例

redis> JSON.SET feature $ '{"enabled":true,"nested":{"flag":false},"id":123}'
OK# ➊ 单路径翻转
redis> JSON.TOGGLE feature $.enabled
1) (integer) 0              # false# ➋ 多路径翻转
redis> JSON.TOGGLE feature $..flag
1) (integer) 1              # nested.flag false → true# ➌ 非布尔字段
redis> JSON.TOGGLE feature $.id
1) (nil)redis> JSON.GET feature $
"[{\"enabled\":false,\"nested\":{\"flag\":true},\"id\":123}]"

5 · 典型使用场景

场景描述建议组合
特性开关 (Feature Toggle)打开 / 关闭实验功能JSON.MGET 批量查开关 + JSON.TOGGLE 动态翻转
任务完成标记任务完成后置 donetrue失败重试时再次 TOGGLE 复位
二元状态机资源占用 (locked) 字段 true/false配合 WATCH 做乐观锁
反向 AB 实验随机翻转用户 groupA 字段做对照批量脚本调用 JSON.TOGGLE

6 · 踩坑与注意

现象对策
字段类型不是布尔返回 nil,值不变初始化时固定字段类型;或先 JSON.TYPE 校验
多路径扫描大文档时间复杂度 O(N)避免 $..flag 通配,改用精确路径
版本兼容RedisJSON 1.x 无此指令部署前确认插件版本≥2.0
误操作连续翻转状态乱跳搭配 NX/XX 或 Lua 脚本加条件判断

7 · Go-Redis 完整示例

依赖:github.com/redis/go-redis/v9、RedisJSON ≥ 2.0

package mainimport ("context""fmt""log""github.com/redis/go-redis/v9"
)func main() {ctx := context.Background()rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"})defer rdb.Close()// 1️⃣ 初始化文档_, err := rdb.Do(ctx, "JSON.SET", "task:1001", "$",`{"title":"write blog","done":false}`).Result()if err != nil { log.Fatal(err) }// 2️⃣ 原子翻转 doneres, _ := rdb.Do(ctx, "JSON.TOGGLE", "task:1001", "$.done").Slice()fmt.Println("done =", res[0]) // 1 (true)// 3️⃣ 再次翻转以复位rdb.Do(ctx, "JSON.TOGGLE", "task:1001", "$.done")// 4️⃣ 读取验证state, _ := rdb.Do(ctx, "JSON.GET", "task:1001", "$.done").Text()fmt.Println("current done:", state) // false
}

批量翻转示例(Pipeline)

pipe := rdb.Pipeline()
keys := []string{"task:1", "task:2", "task:3"}
for _, k := range keys {pipe.Do(ctx, "JSON.TOGGLE", k, "$.done")
}
if _, err := pipe.Exec(ctx); err != nil {log.Fatal(err)
}

8 · 性能与并发建议

  1. Pipeline / Lua 脚本

    • 高并发批量翻转时使用 Pipeline 减少 RTT。

    • 若需条件判断(如仅当 done=false 才翻转),可写 Lua:

      local v=redis.call('JSON.GET',KEYS[1],'$.done')
      if v=='false' thenreturn redis.call('JSON.TOGGLE',KEYS[1],'$.done')[1]
      end
      return -1
      
  2. 慢日志监控

    • 大文档 + 多路径 ($..flag) 易触发 SLOWLOG
  3. 幂等 API

    • Web 接口里应返回翻转后值,而不是固定 200 来避免并发写乱序。

9 · 与其他指令的协同

目标指令组合说明
首次写布尔 + 后续翻转JSON.SET ... NXJSON.TOGGLE先用 NX 保证类型,后续直接翻转
布尔统计FT.AGGREGATE + JSON.TOGGLERediSearch 聚合统计 true/false 数量
布尔值批量置位JSON.SET + JSON.TOGGLE批量清零后一键启用

10 · 小结

  • JSON.TOGGLE 为布尔字段提供了 原子取反 能力,消除读-改-写竞态。
  • 返回值 1 / 0 表示翻转后的 true / false,可直接用作状态。
  • 多路径场景要注意 O(N) 复杂度,能精准就精准。
  • 在 Go-Redis 中只需 Do() 调用即可,Pipeline 可批量操作。
  • 结合 Lua、RediSearch、NX/XX 等组件,可构建更复杂的布尔状态机和实验平台。

至此,RedisJSON 字符串与布尔操作的核心指令你已全部掌握。下次需要快速翻转开关或标记任务完成,别忘了 JSON.TOGGLE 这把利器!如有问题,欢迎评论交流。

http://www.dtcms.com/a/291960.html

相关文章:

  • 聊聊 iframe:网页中的“窗口”是怎么回事?
  • Vue3 学习教程,从入门到精通,Vue3 循环语句(`v-for`)语法知识点与案例详解(13)
  • rabbitmq 03
  • 《3D printed deformable sensors》论文解读
  • 【初识数据结构】CS61B 中的堆以及堆排序算法
  • 矩阵SVD分解计算
  • 今日Github热门仓库推荐 第八期
  • 3ds Max 云端渲染插件 - 完整 Python 解决方案
  • 锟斤拷与烫烫烫:中文编程界的独特印记
  • Go语言切片(Slice)与数组(Array)深度解析:避坑指南与最佳实践
  • Go语言实战案例-遍历目录下所有文件
  • Go 的第一类对象与闭包
  • 基于单片机智能衣柜/智能衣橱设计
  • Go 并发(协程,通道,锁,协程控制)
  • 【Unity开发】坦克大战项目实现总结
  • Golang避免主协程退出方案
  • GoLang教程007:打印空心金字塔
  • PHP与Web页面交互:从基础表单到AJAX实战
  • 八大作业票(二)受限空间安全作业证
  • 智算中心光纤线缆如何实现自动化计算?
  • 汽车安全 | 汽车安全入门
  • 【机器学习】第五章 聚类算法
  • SpringBoot--Mapper XML 和 Mapper 接口在不同包
  • 基于Kubernetes的微服务CI/CD:Jenkins Pipeline全流程实践
  • 时序数据库 TDengine × Ontop:三步构建你的时序知识图谱
  • 【SVM】支持向量机实例合集
  • Dockerfile:镜像构建
  • 在资源受限单片机中使用printf等可变参函数时的陷阱(2025年7月22日)
  • DF与介质损耗
  • 深入解析谱聚类:RatioCut与Ncut的图拉普拉斯推导