ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

DiceDB 的 JSON.STRLEN 命令详解:查询 JSON 文档中字符串长度

DiceDB 的 JSON.STRLEN 命令详解:查询 JSON 文档中字符串长度 DiceDB 的 JSON.STRLEN 命令详解查询 JSON 文档中字符串长度【免费下载链接】dicedbOpen-source, low-latency key/value engine built on Valkey with query subscriptions and hierarchical storage tiers.项目地址: https://gitcode.com/GitHub_Trending/dic/dicedbJSON.STRLEN是 DiceDB 提供的 JSON 数据操作命令用于返回指定 JSON 文档中某个 JSONPath 所指向的字符串长度。在需要校验字符串字段长度、做数据完整性检查或配合订阅、缓存等实时场景使用时它是最直接的读取手段。读完本文你将掌握JSON.STRLEN的完整语法、参数与返回值规则、各类错误处理方式并理解其在 DiceDB 源码中的底层实现与测试验证。命令概览与适用场景JSON.STRLEN用于读取存储在 DiceDB 中 JSON 文档的字符串字段长度类似于传统 KV 命令中针对字符串值长度判断的能力但作用于 JSON 结构内部。它常与JSON.SET、JSON.GET、JSON.ARRLEN、JSON.OBJLEN等命令配合使用帮助开发者在不拉取完整 JSON 的前提下快速判断某个字符串字段的长度例如检查邮箱、姓名、地址等字段是否符合长度约束。在 DiceDB 的命令注册表中JSON.STRLEN以如下元数据登记见 internal/eval/commands.gojsonStrlenCmdMeta DiceCmdMeta{ Name: JSON.STRLEN, Info: JSON.STRLEN key [path] Report the length of the JSON String at path in key, Arity: -2, KeySpecs: KeySpecs{BeginIndex: 1}, IsMigrated: true, NewEval: evalJSONSTRLEN, }其中Arity: -2表示该命令至少接受 1 个参数key参数数量可变KeySpecs.BeginIndex: 1表明第一个参数即 keyNewEval: evalJSONSTRLEN指向其求值实现函数。语法与参数JSON.STRLEN key [path]参数说明类型是否必填key存储 JSON 文档的键名。String是path指向 JSON 文档内字符串的 JSONPath 表达式该路径下必须包含字符串值。String否其中path为可选参数。未提供path时DiceDB 默认以根路径$作为查询路径。在源码中根路径常量定义为defaultRootPath $见 internal/eval/eval.go。返回值规则JSON.STRLEN的返回值取决于路径匹配结果条件返回值指定路径下找到 JSON 字符串返回字符串长度整数JSONPath 包含*或$..等通配表达式按路径匹配顺序返回每个字符串的长度非字符串值对应位置返回nilkey 不存在返回(nil)路径存在但指向非字符串值返回nil显式路径场景或类型错误未指定 path 场景路径不存在返回(empty array)行为规则详解执行JSON.STRLEN时DiceDB 按以下顺序处理与实现函数evalJSONSTRLEN的逻辑一一对应key 不存在命令返回(nil)不产生错误。对应实现中store.Get(key)返回nil时直接返回空结果见 internal/eval/store_eval.go。未指定 path默认使用根路径$。若根数据是字符串返回表示长度的整数若根数据不是字符串返回类型不匹配错误见下方错误章节。实现中会对数字类型做二次判定将float64进一步区分为integer或number见 internal/eval/store_eval.go。显式指定$根路径若根数据是字符串返回包含长度的单元素数组如[8]否则返回单元素数组[nil]见 internal/eval/store_eval.go。指定路径且指向字符串返回该字符串的长度。通配符匹配多个结果结果以列表形式返回每个字符串长度按匹配顺序排列非字符串位置返回nil见 internal/eval/store_eval.go。关于长度的计算口径从实现看长度由 Go 的len()函数对字符串值求取如int64(len(jsonData.(string)))。Go 的len()返回的是字符串的字节长度对纯 ASCII 文本英文、数字、常见标点而言字节数即字符数若字符串包含中文等多字节字符返回的是 UTF-8 编码下的字节数这一点与字符计数可能存在差异使用时需注意。错误处理执行JSON.STRLEN可能触发以下错误1. 参数数量错误(error) ERROR wrong number of arguments for JSON.STRLEN command当传入参数数量不正确时触发。实现中在参数不足len(args) 1时返回diceerrors.ErrWrongArgumentCount(JSON.STRLEN)其消息模板为wrong number of arguments for %s command见 internal/eval/store_eval.go 与 internal/errors/errors.go。2. JSONPath 解析失败(error) ERROR invalid JSONPath当提供的 JSONPath 表达式无法解析时触发。实现中jp.ParseString(path)解析失败后返回diceerrors.ErrJSONPathNotFound(path)该错误实际消息格式为path %s does not exist见 internal/eval/store_eval.go 与 internal/errors/errors.go。3. 类型不匹配错误未指定 path 时(error) WRONGTYPE wrong type of path value - expected string but found {数据类型}当提供了有效 key 但未指定 path默认根路径$且根数据不是字符串时触发。错误消息由diceerrors.ErrUnexpectedJSONPathType(string, jsonDataType)生成模板为wrong type of path value - expected string but found %s见 internal/eval/store_eval.go 与 internal/errors/errors.go。可出现的实际类型包括object、number、integer、array、boolean。4. 键类型错误(error) WRONGTYPE Operation against a key holding the wrong kind of value当 key 存在但存储的不是 JSON 类型对象时触发实现通过object.AssertType(obj.Type, object.ObjTypeJSON)校验并返回diceerrors.ErrWrongTypeOperation见 internal/eval/store_eval.go。示例使用以下示例基于如下 JSON 文档存储于 keyuser:1001{ name: John Doe, email: john.doeexample.com, address: { city: New York, zipcode: 10001 } }基础用法获取顶层字符串长度JSON.STRLEN user:1001 $.name (integer) 8$.name指向John Doe长度为 8。嵌套 JSON 字符串JSON.STRLEN user:1001 $.address.city (integer) 8$.address.city指向New York长度为 8。路径不存在JSON.STRLEN user:1001 $.phone (empty array)路径$.phone在文档中不存在JSONPath 查询结果为空集返回空数组。路径指向非字符串值JSON.STRLEN user:1001 $.address (nil)$.address指向一个对象而非字符串返回nil。通配符与递归匹配假设文档为{name:jerry,partner:{name:tom}}JSON.STRLEN doc $..name 1) (integer) 5 2) (integer) 3递归路径$..name同时命中jerry5与tom3结果按匹配顺序以数组返回见 tests0/json_test.go 中的jsonstrlen nested用例。未指定 path 的场景JSON.SET doc $ hello JSON.STRLEN doc (integer) 5根数据为字符串时直接返回长度若根数据为对象、数组或布尔等类型则按错误章节第 3 条返回类型不匹配错误。底层实现原理JSON.STRLEN的求值函数为evalJSONSTRLEN见 internal/eval/store_eval.go其核心流程为校验参数数量至少需要key从存储中取出对象key 不存在则直接返回nil未提供 path 时对根数据做类型判定数字类型会先区分number与integer只有string类型才返回长度否则返回类型错误提供 path 时先断言对象是 JSON 类型再处理$根路径返回单元素数组使用 JSONPath 解析器jp.ParseString(path)解析并执行expr.Get(jsonData)完成查询对查询结果逐个判定类型字符串返回int64(len(...))非字符串追加nil最终以[]interface{}数组形式返回。从实现注释看该函数通过递归下降为每个匹配路径返回整数回复数组Returns by recursive descent an array of integer replies for each path与 RedisJSON 生态中JSON.STRLEN的语义保持一致。测试验证DiceDB 为JSON.STRLEN提供了单元测试与集成测试双重覆盖单元测试testEvalJSONSTRLEN见 internal/eval/eval_test.go覆盖了空参数nil输入、key 不存在、根路径为 object/number/integer/array/boolean 五种非字符串类型、根路径为字符串、子路径为字符串、子路径非字符串等 9 类场景。其中子路径用例使用$..name递归匹配验证了通配符行为。集成测试tests0/json_test.go 中的TestJSONSTRLEN通过真实客户端命令验证了根路径返回(nil)、递归多结果[5, 3]、无 path 时 object/boolean/array/integer/number 五类根数据的错误消息。这些测试直接印证了文档中描述的行为规则尤其是无 path 时报类型错误、显式$返回nil数组这一容易混淆的差异点。实践建议与注意事项优先使用显式 path如需判断嵌套字段长度务必传入完整的 JSONPath省略 path 时只检查根数据根为非字符串会直接报错。理解nil与空数组的区别路径不存在返回空数组路径存在但值非字符串返回nil两者语义不同客户端处理时应区分。通配符结果的顺序*、$..等匹配多个节点时结果顺序与文档中的出现顺序一致非字符串节点对应位置为nil遍历结果时需做空值判断。长度口径长度是 Go 字节长度处理含多字节字符如中文、emoji的字符串时结果不等于肉眼可见的字符数需结合业务自行换算。配套命令字符串的写入与追加可分别使用JSON.SET与JSON.STRAPPEND后者见 tests0/json_test.go读取长度则统一使用JSON.STRLEN两者配合可完成字符串字段的写入—校验—更新闭环。参考实现文件命令注册元数据internal/eval/commands.go求值实现evalJSONSTRLENinternal/eval/store_eval.go根路径常量defaultRootPathinternal/eval/eval.go错误定义与消息模板internal/errors/errors.go单元测试internal/eval/eval_test.go集成测试tests0/json_test.go【免费下载链接】dicedbOpen-source, low-latency key/value engine built on Valkey with query subscriptions and hierarchical storage tiers.项目地址: https://gitcode.com/GitHub_Trending/dic/dicedb创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进