RedisJSON 路径语法深度解析与实战
一、两种路径语法概览
语法类型 | 触发标志 | 简介 |
---|---|---|
JSONPath | 以 $ 开头 | 全功能路径,支持递归 (.. )、通配符 (* )、切片 ([start:end:step] )、过滤 (?() )、脚本表达式等 |
Legacy | 以 . 或键名开头 | 早期版本(v1)遗留语法,只支持简单的点式和中括号,不支持通配符/过滤 |
RedisJSON 会根据第一个字符自动判断:
- 以
$
开头 → JSONPath - 否则 → Legacy
二、JSONPath 语法要点
语法 | 功能 | ||
---|---|---|---|
$ | 根节点 | ||
. 、[] | 直接子节点选择 | ||
.. | 递归搜索,匹配任意层级的同名字段 | ||
* | 通配符,匹配当前节点下所有子元素 | ||
[i] | 数组下标,支持负数(-1 表示最后一个) | ||
[start:end:step] | 数组切片,如 [0:2] 、[:3] 、[::2] | ||
[?()] | 过滤表达式,支持比较运算符 ==,!=,<,<=,>,>=,=~ 以及逻辑运算 `&&, | ` | |
@ | 当前元素引用,在过滤器内用 @.field 访问 | ||
() | 脚本表达式 |
提示:在 CLI 中,整个 JSONPath 通常要用单引号包裹,以免 Shell 把
$
、*
等展开。
三、Legacy 语法要点
- 以点号
.
或直接键名开头(可省略根节点.
) - 支持
a.b.c
、a["key-with-special"]
、a[0]
、a[-1]
- 不支持通配符、递归、切片、过滤等高级特性
四、实战示例
假设已在 Redis 中载入以下文档(键名 bikes:inventory
,见你的示例):
# 省略 JSON.SET 代码,假设文档已存在
1. 基本查询
# 获取整个 inventory 下所有子数组(mountain_bikes、commuter_bikes)
JSON.GET bikes:inventory '$.inventory.*'
2. 提取所有山地车型号
JSON.GET bikes:inventory '$.inventory.mountain_bikes[*].model'
# 或
JSON.GET bikes:inventory '$..mountain_bikes[*].model'
# 返回 ["Phoebe","Quaoar","Weywot"]
3. 递归查询
# 查找所有 model 字段
JSON.GET bikes:inventory '$..model'
# 返回 ["Phoebe","Quaoar","Weywot","Salacia","Mimas"]
4. 数组切片
# 前两个山地车
JSON.GET bikes:inventory '$.inventory.mountain_bikes[0:2].model'
# 返回 ["Phoebe","Quaoar"]
5. 过滤表达式
# 价格 < 3000 且 重量 < 10 的山地车
JSON.GET bikes:inventory '$..mountain_bikes[?(@.price < 3000 && @.specs.weight < 10)]'
# 材料为 alloy 的所有车型型号
JSON.GET bikes:inventory '$..[?(@.specs.material == "alloy")].model'
# 返回 ["Weywot","Mimas"]
# 正则匹配材料以 "al-" 开头(v2.4.2+ 支持 =~)
JSON.GET bikes:inventory '$..[?(@.specs.material =~ "(?i)al")].model'
# 返回 ["Quaoar","Weywot","Salacia","Mimas"]
6. 更新与增删
# 所有价格统一减 100 / 加 100
JSON.NUMINCRBY bikes:inventory '$..price' -100
JSON.NUMINCRBY bikes:inventory '$..price' 100
# 对价格 <2000 的车型,设为 1500
JSON.SET bikes:inventory '$.inventory.*[?(@.price<2000)].price' 1500
# 向所有价格 <2000 的 colors 数组追加 "pink"
JSON.ARRAPPEND bikes:inventory '$.inventory.*[?(@.price<2000)].colors' '"pink"'
五、Legacy 语法示例
# 等同于 $.inventory.mountain_bikes[0].model
JSON.GET bikes:inventory .inventory.mountain_bikes[0].model
# 或
JSON.GET bikes:inventory inventory["mountain_bikes"][1].model
六、性能与注意事项
-
定位开销:路径深度越深、对象键越多、过滤条件越复杂,查询时间越长;推荐预先
JSON.GET
小范围字段或使用聚合后端做二次过滤。 -
过滤器正则:
=~
支持 PCRE 风格,默认部分匹配,需精确匹配请在模式前后加^
、$
。 -
路径返回格式:
- 单路径 → 顶层返回数组
- 多路径 → 返回对象,每个路径对应一个数组
-
CLI 转义:Windows PowerShell 与 Bash 对引号处理不同,必要时可多层转义或改用客户端 SDK。
通过掌握上述示例与要点,你就能灵活使用 RedisJSON 强大的路径查询和更新能力,实现对嵌套 JSON 的高效操作。祝编程愉快!