
DiceDB JSON.ARRAPPEND 命令详解向 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.ARRAPPEND是 DiceDB 中 DiceDBJSON 模块提供的原生 JSON 命令之一用于向指定 JSON 文档中某个路径所指向的数组末尾追加一个或多个 JSON 值并返回追加后数组的新长度。本文以仓库中的官方命令文档 JSON.ARRAPPEND.md 为核心骨架结合 DiceDB 的命令注册、求值器实现与测试用例完整讲解其语法、参数、返回值、错误语义与底层执行原理读者可以据此在 DiceDB 中正确、高效地完成 JSON 数组的动态扩展操作。命令概述DiceDB 是一个开源、低延迟的键值引擎low-latency key/value engine通过 DiceDBJSON 模块提供原生的 JSON 数据能力。JSON.ARRAPPEND正是这套 JSON 命令体系中的数组追加原语与JSON.SET、JSON.GET、JSON.ARRLEN、JSON.ARRINSERT、JSON.ARRPOP等命令配合可以在不读取、反序列化整个文档的前提下对嵌套 JSON 数组进行就地修改。从命令注册表看该命令被标记为已迁移IsMigrated: true其元数据定义在 internal/eval/commands.gojsonarrappendCmdMeta DiceCmdMeta{ Name: JSON.ARRAPPEND, Info: JSON.ARRAPPEND key [path] value [value ...] Returns an array of integer replies for each path, the arrays new size, or nil, if the matching JSON value is not an array., Arity: -3, IsMigrated: true, NewEval: evalJSONARRAPPEND, }Arity: -3表示该命令至少需要 3 个参数key、path、至少一个 value且参数个数可变实际执行逻辑由evalJSONARRAPPEND函数承担见下文源码级实现剖析。语法JSON.ARRAPPEND key path json_value [json_value ...]key必填要操作的键。path必填指向 JSON 文档中数组位置的 JSONPath 表达式。json_value必填一个或多个要追加的 JSON 值可重复传入多个。参数说明参数类型说明keyString存储 JSON 文档的键名。pathStringJSONPath 表达式用于定位 JSON 文档中数组所在的位置。json_valueJSON一个或多个要追加到数组末尾的 JSON 值。这些值必须是合法的 JSON 数据类型例如字符串、数字、对象、数组、布尔值或null。需要特别强调的是json_value是按JSON 字面量解析的追加普通字符串时必须带引号如cherry追加对象/数组时使用{...}/[...]字面量。解析工作由底层实现调用sonic.UnmarshalString完成见 internal/eval/store_eval.go因此任何非法 JSON 输入都会直接报错。返回值Integer追加操作完成后数组的新长度。当使用递归 JSONPath如$..一次匹配多个数组时返回由各数组新长度组成的整数数组其中被匹配到但不是数组的节点对应位置返回nil该行为在官方文档的Return Value一节未展开但已被源码与测试明确证实详见下文。行为语义JSON.ARRAPPEND执行时会将指定的 JSON 值依次追加到key下 JSON 文档中path所指向数组的末尾。若路径不存在或路径指向的值不是数组命令会报错若键不存在命令报错详见下文错误处理其中文档描述与当前源码实现存在一处细微差异已在实现剖析中说明。该命令具备以下关键语义就地修改数组元素是追加到目标数组的尾部原有元素顺序与内容保持不变。支持一次追加多个值多个json_value按命令行给定的先后顺序依次入列。支持多路径匹配当 JSONPath 使用递归下降语法如$..score时会对所有匹配到的数组执行追加。错误处理官方文档列出了如下错误场景结合源码internal/errors/errors.go可确认其错误码来源错误场景错误消息触发条件类型错误Wrong type of value or key(error) WRONGTYPE Operation against a key holding the wrong kind of value键中存储的不是 JSON 类型值。源码中通过object.AssertType(obj.Type, object.ObjTypeJSON)校验失败时返回ErrWrongTypeOperationinternal/errors/errors.go。键不存在Invalid Key(error) ERR key does not exist对不存在的键执行追加。路径不存在Invalid Path(error) ERR path %s does not existJSON 文档中不存在path指定的位置对应ErrJSONPathNotFoundinternal/errors/errors.go。路径处不是数组Non Array Value at Path(error) ERR path is not an arraypath指向的值不是数组。非法的 JSON 值Invalid JSON(error) ERR invalid JSON传入的json_value不是合法的 JSON 字面量。此外还有一类未在文档中单独列出、但由Arity: -3决定的错误当参数个数少于 3 个即缺少 value时返回ErrWrongArgumentCount(JSON.ARRAPPEND)错误internal/errors/errors.go。示例用法以下示例均基于 DiceDB 默认端口 7379 的命令行客户端与官方文档一致。向数组追加单个值127.0.0.1:7379 JSON.SET myjson . {numbers: [1, 2, 3]} OK 127.0.0.1:7379 JSON.ARRAPPEND myjson .numbers 4 (integer) 4 127.0.0.1:7379 JSON.GET myjson {\numbers\:[1,2,3,4]}向数组追加多个值127.0.0.1:7379 JSON.SET myjson . {fruits: [apple, banana]} OK 127.0.0.1:7379 JSON.ARRAPPEND myjson .fruits cherry date (integer) 4 127.0.0.1:7379 JSON.GET myjson {\fruits\:[\apple\,\banana\,\cherry\,\date\]}键不存在时报错127.0.0.1:7379 JSON.ARRAPPEND nonexistingkey .array 1 (error) ERR key does not exist路径不存在时报错127.0.0.1:7379 JSON.SET myjson . {numbers: [1, 2, 3]} OK 127.0.0.1:7379 JSON.ARRAPPEND myjson .nonexistingpath 4 (error) ERR path .nonexistingpath does not exist路径不是数组时报错127.0.0.1:7379 JSON.SET myjson . {object: {key: value}} OK 127.0.0.1:7379 JSON.ARRAPPEND myjson .object 4 (error) ERR path is not an array传入非法 JSON 时报错127.0.0.1:7379 JSON.SET myjson . {numbers: [1, 2, 3]} OK 127.0.0.1:7379 JSON.ARRAPPEND myjson .numbers invalidjson (error) ERR invalid JSON进阶在根路径处追加根文档本身就是数组DiceDB 的 JSON 文档允许根节点即为数组此时可用$作为路径直接在根数组上追加该用法已被单元测试覆盖见 internal/eval/eval_test.go127.0.0.1:7379 JSON.SET arr $ [1,2,3] OK 127.0.0.1:7379 JSON.ARRAPPEND arr $ 6 (integer) 4进阶递归路径一次追加多个数组使用$..score这类递归 JSONPath 时命令会命中所有匹配的数组并分别追加返回各数组的新长度127.0.0.1:7379 JSON.SET doc $ {partner:{name:tom,score:[10]},partner2:{score:[10,20]}} OK 127.0.0.1:7379 JSON.ARRAPPEND doc $..score 10 1) (integer) 2 2) (integer) 3进阶追加对象与数组等复合值json_value支持任意合法 JSON包括对象和数组字面量127.0.0.1:7379 JSON.SET doc $ {a:[{b:1}]} OK 127.0.0.1:7379 JSON.ARRAPPEND doc $.a {c:3} (integer) 2 127.0.0.1:7379 JSON.SET arr $ {a:[[1,2]]} OK 127.0.0.1:7379 JSON.ARRAPPEND arr $.a [1,2,3] (integer) 2源码级实现剖析JSON.ARRAPPEND的完整执行逻辑位于 internal/eval/store_eval.go 的evalJSONARRAPPEND函数其处理流程可拆解为以下五个阶段参数校验要求len(args) 3即 key、path、至少一个 value否则返回ErrWrongArgumentCount。取键与类型校验通过store.Get(key)获取对象对象不存在或已过期时返回NIL结果。随后调用object.AssertType(obj.Type, object.ObjTypeJSON)校验对象确为 JSON 类型否则返回WRONGTYPE错误。JSONPath 解析调用jp.ParseString(path)将路径字符串解析为 JSONPath 表达式解析失败返回ErrJSONPathNotFound(path)。值解析对每个json_value调用sonic.UnmarshalString(v, parsedValue)解析为 JSON 值任何解析失败都会以通用错误形式返回——这就是非法 JSON错误的来源。就地修改核心通过expr.Modify(jsonData, callback)完成回调函数检查当前节点是否为[]interface{}数组是则执行arr append(arr, parsedValues...)并记录新长度到resultsArray不是数组则在该位置记入NIL。Modify返回后若全程没有任何数组被修改即路径完全不存在或没有匹配到数组函数返回ErrJSONPathNotFound(path)否则将修改后的数据写回obj.Value并返回resultsArray。这一实现揭示了一个值得注意的细节当前源码中当 key 不存在或已过期时命令返回的是(nil)Result: NIL, Error: nil而不是文档中描述的ERR key does not exist错误。同时递归路径下部分匹配成功、部分不是数组的场景会得到[长度, (nil), ...]的混合结果而不是整体报错。这与 tests0/json_test.go 中的TestJsonARRAPPEND用例如JSON.ARRAPPEND nested with nil期望返回[int64(2), (nil)]完全吻合实际使用时请以线上实例的返回行为为准。测试验证DiceDB 为该命令提供了两层测试覆盖单元测试internal/eval/eval_test.go 直接构造evalJSONARRAPPEND的输入输出覆盖追加嵌套数组值$.a追加[1,2,3]、追加对象值{c:3}、递归多字段追加$..a返回[2,3]、根节点追加$以及向数组追加不同类型值等场景并断言 RESP 编码输出如*2\r\n:2\r\n:3\r\n。端到端测试tests0/json_test.go 通过真实客户端连接执行命令序列覆盖根路径追加、递归追加$..score、递归命中非数组节点返回nil以及混合数据类型等用例。这些测试不仅验证了命令的正确性也为我们理解返回值的各种形态单个整数、整数数组、含nil的混合数组提供了最直接的依据。注意事项与最佳实践确保 DiceDBJSON 模块已加载使用JSON.ARRAPPEND前需要确认实例已启用 DiceDBJSON 模块提供的 JSON 能力。熟悉 JSONPath 语法path使用 JSONPath 表达式定位文档位置。掌握.child、$.root、$..recursive等基础语法可以更精准地控制追加目标递归表达式会一次命中多个数组并返回多值结果。值为 JSON 字面量追加字符串必须加引号cherry追加数字、布尔值、null、对象、数组时按 JSON 语法书写否则会触发invalid JSON错误。关注返回语义单路径场景返回追加后数组的新长度可直接用于判断操作是否生效递归路径场景返回长度数组其中nil表示对应节点不是数组。结合其他 JSON 命令使用JSON.ARRAPPEND通常与JSON.SET初始化文档、JSON.GET查看结果、JSON.ARRLEN查询长度、JSON.ARRPOP/JSON.ARRTRIM数组收缩配合构成完整的数组生命周期管理。通过本文档读者可以全面掌握JSON.ARRAPPEND的语法、语义与实现细节进而在 DiceDB 中自如地维护 JSON 数组数据。【免费下载链接】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),仅供参考