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

RedisJSON 技术揭秘(五)`JSON.ARRPOP` 原子弹出 修改数组的终极手段

1、指令速查

JSON.ARRPOP <key> [path [index]]
  • key:要修改的 Redis 键

  • path(可省略,默认 $):JSONPath,可用 .. / [*] 多路径匹配

  • index(可省略,默认 -1):要弹出的位置

    • 0 → 头元素
    • -1 → 尾元素(等同于栈/队列 pop)
    • 其他负值 → 从末尾倒数
    • 越界会被自动钳位到数组两端
    • 空数组返回 null

返回值:与路径一一对应的被弹出元素;若路径不是数组 → nil

时间复杂度

  • 单路径且弹出尾部O(1)
  • 其他情况(头部 / 中间 / 多路径)→ O(N) ,N 为数组长度

2、核心优势

  1. 原子性:读 + 删一步到位,避免并发脏写
  2. 网络极简:只需一次 RTT
  3. 读写对等:返回值就是被删元素,可立即写入别处或计算
  4. 队列 / 栈场景天然契合:尾弹 (index = -1) = Stack;头弹 (index = 0) = Queue

3、CLI 实战:耳机产品的 max_level 管理

3.1 创建数据

JSON.SET key $ '[{"name":"Healthy","max_level":[60,70,80]},{"name":"Noisy","max_level":[80,90,100,120]}]'

3.2 弹出第二个产品的首个 max_level

redis> JSON.ARRPOP key $.[1].max_level 0
1) "80"

数组变为 [90,100,120],同时我们拿到了被删除的 80

3.3 再 Tail-Pop

redis> JSON.ARRPOP key $.[1].max_level    # index 默认为 -1
1) "120"

现在数组仅剩 [90,100]

4、跨语言示例

Python(redis-py ≥ 5.0)

from redis import Redis
r = Redis(decode_responses=True)popped = r.execute_command("JSON.ARRPOP", "key", "$.[1].max_level", 0
)
print(popped)   # ["80"]

Node.js(@redis/client)

import { createClient } from 'redis';
const cli = createClient(); await cli.connect();const [pop] = await cli.json.arrPop('key', '$.[1].max_level',  -1);
console.log(pop); // 120

Go(go-redis/v9)

popped, _ := rdb.Do(ctx, "JSON.ARRPOP","key", "$.[0].max_level", -1).StringSlice()
log.Println(popped[0])   // "80"

5、典型应用场景

场景玩法
任务队列Workers:ARRPOP tasks $.queue 0 → 取出并删除头任务
缓存逐出策略列表存最近记录,长度 > limit 时先 ARRPOP key $.list 0ARRAPPEND
移动元素ARRPOP src + ARRAPPEND dst 可原子搬迁(用 Lua/事务更稳)
限流每次写前 ARRLEN,超限则 ARRPOP 头部旧数据

6、性能&陷阱

  • 优先尾弹:尾部 ARRPOP → O(1),头/中间 O(N)
  • 多路径慎用$..array 会对每个匹配执行弹出,整体 O(N)
  • 空数组/不存在:返回 null,注意判空
  • 并发栈/队列:多个客户端同时 ARRPOP 尾部仍是安全的,但若需要一次弹出并插入别的键建议 Lua 脚本或 MULTI 保证一致性

7、与数组家族指令的协同

  • ARRAPPEND/ARRINSERT:弹后再插,重排元素
  • ARRLEN:弹前统计,判断是否已空
  • ARRINDEX:先查后弹,删除指定值
  • ARRTRIM(下一篇):批量裁剪 vs 单条弹出

8、结语

至此,RedisJSON 对数组的增(APPEND / INSERT)查(INDEX / LEN)、**删(POP)**已全部解锁。JSON.ARRPOP 通过原子弹出让你在队列、限流与实时数据清洗场景中如虎添翼。下一篇,我们将迎来本系列终章——JSON.ARRTRIM,聚焦批量裁剪与窗口化数组,敬请期待!

http://www.lryc.cn/news/586884.html

相关文章:

  • 基于Java Web的销售管理系统设计系统
  • 操作系统--用户态和内核态
  • MongoDB对接SpringBoot【大数据存储】
  • ref 和 reactive
  • https交互原理
  • [Subtitle Edit] 字幕格式处理 | .Net依赖管理(NuGet)
  • Python----OpenCV(图像分割——彩色图像分割,GrabCut算法分割图像)
  • LeetCode--44.通配符匹配
  • Mybatis 两级缓存可能导致的问题
  • Java4种设计模式详解(单例模式、工厂模式、适配器模式、代理模式)
  • 笔记/sklearn中的数据划分方法
  • 赛力斯6月新能源汽车销量46086辆,同比增长4.44%
  • JavaScript加强篇——第九章 正则表达式高级应用(终)
  • Linux编程:6、进程通信-信号量与共享内存
  • OpenLayers 入门指南【二】:坐标系与投影转换
  • linux进程信号II
  • Node.js特训专栏-实战进阶:16. RBAC权限模型设计
  • 基于YOLOv7的改进模型:集成Swin Transformer和ASFF模块
  • 26-计组-数据通路
  • 【软件开发】使用 Spring WebFlux 进行请求校验
  • iOS ish app 打印时间
  • HJ8 合并表记录 10:35
  • Vue中的render()函数
  • 【LeetCode数据结构】单链表的应用——反转链表问题、链表的中间节点问题详解
  • 为什么要有延时回调?
  • 【实证分析】上市公司绿色战略数据集(2000-2023年)
  • 如何设计一个合理的 Java Spring Boot 项目结构
  • C++ 强制类型转换
  • 【读书笔记】《C++ Software Design》第六章深入剖析 Adapter、Observer 和 CRTP 模式
  • 开机自动启动同花顺,并设置进程优先级为高