> 技术文档 > RedisJSON 指令精讲JSON.TYPE 一眼看清字段类型

RedisJSON 指令精讲JSON.TYPE 一眼看清字段类型


1 · 背景与价值

  • 动态 JSON 文档 经常混合数字、布尔、字符串、数组、对象等多种类型
  • 在对字段条件写入NX/XX)、增量操作NUMINCRBY)、追加 等之前,我们必须先确认它的真实类型。
  • JSON.TYPE 提供 O(1) 的字段级类型探测,省去把整段 JSON 拉回客户端再解析的麻烦,也避免了类型误判导致的运行时错误。

2 · 指令总览

指令 功能 复杂度 JSON.TYPE key [path] 返回指定路径 JSON 值的类型 O(1)(单路径) / O(N)(多路径,与键大小相关)
  • 可用版本:RedisJSON ≥ 1.0
  • ACL 标签@json @read @slow
  • 默认路径$(根)
  • 可返回类型stringintegernumberbooleanobjectarraynull

RedisJSON 将整数/浮点区分为 integer / number;空值返回 null 字面量。

3 · 语法与返回值

JSON.TYPE  []
  • 单路径:直接返回指定节点的类型字符串;
  • 多路径:按匹配点顺序,返回一个字符串数组;
  • 不存在/路径不匹配:返回空数组 []
  • 目标为 JSON.null:返回 \"null\" 而非 nil

示例:

redis> JSON.SET doc $ \'{\"a\":2,\"nested\":{\"a\":true},\"foo\":\"bar\"}\'OKredis> JSON.TYPE doc $..a1) \"integer\"2) \"boolean\"redis> JSON.TYPE doc $.nested\"object\"

4 · 典型使用场景

场景 描述 推荐组合 安全写入 写前确认字段类型,避免类型冲突 JSON.TYPEJSON.SET NX/XX 动态路由 根据字段不同类型走不同业务流程 JSON.TYPE 结果做 switch case 增量/追加 只有当字段是数字才 NUMINCRBY,是字符串才 STRAPPEND JSON.TYPE 判别后分支调用 数据治理 批量扫描文档结构,统计字段类型分布 对所有键执行 JSON.TYPE 收集

5 · 踩坑与注意

坑 现象 解决方案 多路径扫描大文档 $..field 性能差 精确路径替代通配,或分层调用 空数组/空对象 返回 array / object,但内容为空 仍需业务层判断长度 null 与 nil 混淆 JSON 值为 null 时类型是 \"null\",路径不存在则空数组 判空时区分两者 浮点数类型 返回 number 而非 float 整数 integer,其余数字 number

6 · Go-Redis 实战代码

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()// 初始化测试文档_, err := rdb.Do(ctx, \"JSON.SET\", \"conf:1\", \"$\",`{\"flag\":true,\"quota\":100,\"meta\":{\"desc\":\"demo\"},\"items\":null}`).Result()if err != nil { log.Fatal(err) }// 1️⃣ 单路径判型t, _ := rdb.Do(ctx, \"JSON.TYPE\", \"conf:1\", \"$.flag\").Text()fmt.Println(\"$.flag ->\", t) // boolean// 2️⃣ 根据类型做不同操作switch t {case \"boolean\":rdb.Do(ctx, \"JSON.TOGGLE\", \"conf:1\", \"$.flag\")case \"integer\":rdb.Do(ctx, \"JSON.NUMINCRBY\", \"conf:1\", \"$.flag\", 1)default:fmt.Println(\"未知类型,不操作\")}// 3️⃣ 多路径批量判型res, _ := rdb.Do(ctx, \"JSON.TYPE\", \"conf:1\", \"$..*\").Slice()fmt.Println(\"全字段类型:\", res)}

7 · 性能与监控建议

  1. Pipeline

    • 大批量键 (万级) 需要类型检查时,使用 Pipeline 降低 RTT。
  2. 配合 Lua 做原子校验-写入

    • 示例:只在类型为 integer 时自增,否则返回错误。

      local t = redis.call(\'JSON.TYPE\', KEYS[1], ARGV[1])if t[1] == \'integer\' then return redis.call(\'JSON.NUMINCRBY\', KEYS[1], ARGV[1], ARGV[2])endreturn redis.error_reply(\'type mismatch\')
  3. 慢日志监控

    • 通配多路径 ($..field) 会遍历整个文档,关注 SLOWLOG

8 · 与其他指令的协同

目标 指令组合 说明 安全增量 JSON.TYPENUMINCRBY 仅在 integer 时自增 安全追加 JSON.TYPESTRAPPEND 先确保是 string 布尔翻转 JSON.TYPETOGGLE 遇到非布尔则跳过或初始化 结构迁移 JSON.TYPE + OBJKEYS/ARRLEN 先探测类型,再读取子结构

9 · 小结

  • JSON.TYPE 是 RedisJSON 的“类型探针”,在动态文档场景中必备。
  • O(1) 查型可大幅简化客户端逻辑、避免运行时错误。
  • 区分 \"null\" 与空数组返回值 [],避免误判。
  • 精确路径优于通配路径,尤其在大文档或高 QPS 场景。
  • 搭配 Lua/Pipeline,可实现原子校验-写入与批量治理。

至此,RedisJSON 字段级读写 + 类型判断工具链已经完整。灵活运用 TYPE + SET/STRAPPEND/STRLEN/TOGGLE/NUMINCRBY,即可构建一个高效、类型安全、可扩展的 JSON 数据层。
如有更多疑问,欢迎留言讨论!