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

RedisJSON 的 `JSON.ARRAPPEND`一行命令让数组动态生长

1 、 为什么选择 JSON.ARRAPPEND

在传统的键值模型里,若要往数组尾部追加元素,通常需要 取→改→写 三步:

  1. GET 整个 JSON;
  2. 在应用层把元素 push 进数组;
  3. SET 回 Redis。

一条 JSON.ARRAPPEND 则可一次完成,具备三个显著优势:

  • 原子性:整个追加在 Redis 内部完成,无并发写冲突。
  • 网络开销极小:一次往返即可。
  • O(1) 或 O(N) 级别时间复杂度:当路径只命中单个数组时为常数时间;若路径匹配多处才与数组大小成正比 ([AWS 文檔][1])。

2 、语法速查

JSON.ARRAPPEND <key> <path> <value> [value ...]
  • key:待修改的 Redis 键。
  • path:JSONPath,默认为 $
  • value:一个或多个 JSON 值,依次附加到目标数组尾部。

字符串陷阱
要往数组里追加字符串,需再包一层外引号,如:'"blue"'。这是因为 Redis CLI 会把参数当作原始文本;再套一层可避免 Redis 解析器把内部引号剥掉 ([Upstash: Serverless Data Platform][2])。

返回值
与路径一一对应的整型数组,元素为追加后的数组长度;若匹配到的值不是数组,则对应位置返回 nil ([AWS 文檔][1])。

3、动手实践:为商品新增颜色

# ① 创建文档
JSON.SET item:1 $ '{"name":"Noise-cancelling Bluetooth headphones","colors":["black","silver"]
}'
# ② 追加 "blue"
JSON.ARRAPPEND item:1 $.colors '"blue"'
# -> (integer) 3
# ③ 验证
JSON.GET item:1 $.colors
# -> [["black","silver","blue"]]

以上流程仅用一次网络往返就完成数组更新,且返回值 3 表示数组新长度。

4、跨语言示例

4.1 Python(redis-py ≥ 5.0)

from redis import Redis
from redis.commands.json.path import Pathr = Redis(host="localhost", port=6379, decode_responses=True)
r.json().set("item:1", Path.root_path(), {"colors": ["black", "silver"]})
new_len = r.json().arrappend("item:1", Path(".colors"), "blue")
print("新长度:", new_len)   # -> [3]

4.2 Node.js(@redis/client)

import { createClient } from 'redis';const client = createClient();
await client.connect();await client.json.set('item:1', '$', { colors: ['black', 'silver'] });
const [len] = await client.json.arrAppend('item:1', '$.colors', 'blue');
console.log(len); // 3

4.3 Go(go-redis/v9)

rdb := redis.NewClient(&redis.Options{Addr: "localhost:6379"})
_, _ = rdb.Do(ctx, "JSON.SET", "item:1", "$", `{"colors":["black","silver"]}`).Result()
len, _ := rdb.Do(ctx, "JSON.ARRAPPEND", "item:1", "$.colors", `"blue"`).IntSlice()
log.Println(len[0]) // 3

5、性能与内存考量

场景建议说明
单用户操作直接调用 JSON.ARRAPPENDO(1),延迟可忽略
批量写入使用 PipelineMULTI/EXEC减少 RTT,可把 1 ms 延迟压到 0.2 ms
高并发写同一键利用 Redis 分区键Sharding避免热点,单核 RDBGIL 成为瓶颈
极大数组(>10 MB)考虑拆分文档或转 KV 列表巨型 JSON 会拖慢序列化与 AOF

内存层面,RedisJSON 内部以二进制树存储 JSON,每个值至少 8 bytes ([DEV Community][3])。大量小数组元素时,务必关注 RSS。

6、常见误区 & 排错

现象根因解决方案
返回 nil路径指向的值不是数组确认 JSON.TYPE key path
数组里出现多层引号字符串未正确包双引号改用 '"text"'
CLI 追加 JSON 对象失败参数被 shell 吞字符--raw 或文件重定向
性能突降路径命中多处,复杂度 O(N)精确路径或重构文档

7、进阶话题

  1. JSON.ARRINSERTJSON.ARRPOP 搭配
    ARRAPPEND 只能尾插,若需头插可用 ARRINSERT key path 0 value,同时 ARRPOP 支持按索引弹出。
  2. 结合 RedisSearch
    给数组字段加 TAG/TEXT 索引,追加后可实时被搜索,无需重建索引。
  3. 多路径写操作
    JSON.ARRAPPEND key $..colors '"red"' '"green"' 一次更新多处,但复杂度 ≥ O(N)。
  4. 幂等写法
    若不希望重复追加,可先 JSON.ARRINDEX 检查元素是否已存在。

8、结语

JSON.ARRAPPEND 把「往数组尾部追加元素」这件小事做到极致简单,却蕴含了 RedisJSON 的设计哲学:把常见的 JSON 变更下沉到数据库层,用原子指令解除并发焦虑
掌握其用法、理解性能边界、配合其他 JSON 指令组合拳,你就能在高吞吐实时应用中优雅地操纵复杂文档结构。

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

相关文章:

  • vue防内存泄漏和性能优化浅解
  • CSS中@media介绍和使用示例
  • 7.13 note
  • 型模块化协作机器人结构设计cad【1张】三维图+设计说明书
  • 机器人猫咪能否温暖中老年孤独
  • 【Complete Search】-基础完全搜索-Basic Complete Search
  • 摩尔线程MUSA架构深度调优指南:从CUDA到MUSA的显存访问模式重构原则
  • Java: OracleHelper
  • Appium源码深度解析:从驱动到架构
  • Vue3 实现文件上传功能
  • HarmonyOS组件/模板集成创新活动-开发者工具箱
  • Vue配置特性(ref、props、混入、插件与作用域样式)
  • FusionOne HCI 23 超融合实施手册(超聚变超融合)
  • 第七章 算法题
  • NO.4数据结构数组和矩阵|一维数组|二维数组|对称矩阵|三角矩阵|三对角矩阵|稀疏矩阵
  • 电源中的声学-噪声,如何抑制开关电源的噪声
  • 飞算JavaAI:开启 Java 开发 “人机协作” 新纪元
  • 二叉树算法详解和C++代码示例
  • 项目合作复盘:如何把项目经验转化为可复用资产
  • 【C++】第十五节—一文详解 | 继承
  • ArkUI Inspector工具用法全解析
  • 【保姆级图文详解】Spring AI 中的工具调用原理解析,工具开发:文件操作、联网搜索、网页抓取、资源下载、PDF生成、工具集中注册
  • 在 JetBrains 系列 IDE(如 IntelliJ IDEA、PyCharm 等)中如何新建一个 PlantUML 文件
  • jEasyUI 创建带复选框的树形菜单
  • NLP-迁移学习
  • 【PyMuPDF】PDF图片处理过程内存优化分析
  • RHCIA第二次综合实验:OSPF
  • 电阻抗成像肺功能测试数据分析与直方图生成
  • 攻防世界——Web题 very_easy_sql
  • Rust 模块系统:控制作用域与私有性