Redis JSON 数据类型概述 - 适用于 Redis 的 Amazon MemoryDB
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

Redis JSON 数据类型概述

MemoryDB 支持许多用于处理 JSON 数据类型的 Redis 命令。以下是 JSON 数据类型的概述和支持的 Redis 命令的详细列表。

术语

租期 说明

JSON 文档

指 Redis JSON 键的值

JSON 值

指 JSON 文档的子集,包括代表整个文档的根。值可以是容器或容器内的条目

JSON 元素

相当于 JSON 值

支持的 JSON 标准

JSON 格式符合 RFC 7159ECMA-404 JSON 数据交换标准。支持 JSON 文本中的 UTF-8 Unicode

根元素

根元素可以是任何 JSON 数据类型。请注意,在早期的 RFC 4627 中,只允许将对象或数组作为根值。自 RFC 7159 更新以来,JSON 文档的根目录可以是任何 JSON 数据类型。

文档大小限制

JSON 文档以针对快速访问和修改而优化的格式在内部存储。此格式通常会导致比同一文档的等效序列化表示使用稍多的内存。单个 JSON 文档的内存使用限制为 64 MB,这是内存中数据结构的大小,而不是 JSON 字符串的大小。可使用 JSON.DEBUG MEMORY 命令检查 JSON 文档所使用的内存量。

JSON ACL

  • JSON 数据类型完全集成到 Redis 访问控制列表(ACL)功能中。与现有的每数据类型类别(@string、@hash 等)类似,添加了一个新的类别 @json,以简化对 JSON 命令和数据的访问管理。没有其他现有的 Redis 命令属于 @json 类别。所有 JSON 命令均强制执行任何键空间或命令限制和权限。

  • 有五个现有的 Redis ACL 类别已更新为包含新 JSON 命令:@read、@write、@fast、@slow 和 @admin。下表指示 JSON 命令到相应类别的映射。

ACL
JSON 命令 @read @write @fast @slow @admin

JSON.ARRAPPEND

y

y

JSON.ARRINDEX

y

y

JSON.ARRINSERT

y

y

JSON.ARRLEN

y

y

JSON.ARRPOP

y

y

JSON.ARRTRIM

y

y

JSON.CLEAR

y

y

JSON.DEBUG

y

y

y

JSON.DEL

y

y

JSON.FORGET

y

y

JSON.GET

y

y

JSON.MGET

y

y

JSON.NUMINCRBY

y

y

JSON.NUMMULTBY

y

y

JSON.OBJKEYS

y

y

JSON.OBJLEN

y

y

JSON.RESP

y

y

JSON.SET

y

y

JSON.STRAPPEND

y

y

JSON.STRLEN

y

y

JSON.STRLEN

y

y

JSON.TOGGLE

y

y

JSON.TYPE

y

y

JSON.NUMINCRBY

y

y

嵌套深度限制

当 JSON 对象或数组有一个元素本身就是其他 JSON 对象或数组时,该内部对象或数组被称为“嵌套”在外部对象或数组中。最大嵌套深度上限为 128。任何创建包含嵌套深度大于 128 的文档的尝试都将被拒绝,并出现错误。

命令语法

大多数命令均要求将 Redis 键名称作为第一个参数。某些命令还带有一个路径参数。如果该路径参数是可选的且未提供,则默认为根目录。

表示法:

  • 必需的参数括在尖括号内,例如:<key>

  • 可选的参数括在方括号内,例如 [path]

  • 其他可选参数由…表示,例如 [json…]

路径语法

JSON-Redis 支持两种路径语法:

  • 增强的语法 – 遵循由 Goessner 描述的 JSONPath 语法,如下表所示。我们对表中的描述进行了重新排序和修改使其更加清楚。

  • 受限的语法 – 查询功能有限。

注意

某些命令的结果对使用哪种类型的路径语法很敏感。

如果查询路径以“$”开头,则使用的是增强的语法。否则使用的是受限的语法。

增强的语法

符号/表达式 说明

$

根元素

. 或 []

子运算符

..

递归下降

*

通配符。对象或数组中的所有元素。

[]

数组下标运算符。索引从 0 开始。

[,]

联合运算符

[start:end:step]

数组 Slice 运算符

?()

将筛选(脚本)表达式应用于当前的数组或对象

()

筛选表达式

@

用于引用当前正在处理的节点的筛选表达式

==

等于,用于筛选表达式。

!=

不等于,用于筛选表达式。

>

大于,用于筛选表达式。

>=

大于或等于,用于筛选表达式。

<

小于,用于筛选表达式。

<=

小于或等于,用于筛选表达式。

&&

逻辑 AND,用于组合多个筛选表达式。

||

逻辑 OR,用于组合多个筛选表达式。

示例

以下示例基于 Goessner 的示例 XML 数据而构建,我们已通过添加其他字段对数据进行了修改。

{ "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95, "in-stock": true, "sold": true }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99, "in-stock": false, "sold": true }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99, "in-stock": true, "sold": false }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99, "in-stock": false, "sold": false } ], "bicycle": { "color": "red", "price": 19.95, "in-stock": true, "sold": false } } }
路径 说明

$.store.book[*].author

商店中所有书籍的作者

$..author

所有作者

$.store.*

商店的所有会员

$["store"].*

商店的所有会员

$.store..price

商店中所有商品的价格

$..*

JSON 结构的所有递归成员

$..book[*]

所有书籍

$..book[0]

第一本书籍

$..book[-1]

最后一本书籍

$..book[0:2]

前两本书籍

$..book[0,1]

前两本书籍

$..book[0:4]

从索引 0 到 3 的书籍(不包括结尾索引)

$..book[0:4:2]

索引为 0、2 的书籍

$..book[?(@.isbn)]

所有带 isbn 编号的书籍

$..book[?(@.price<10)]

所有价格低于 10 美元的书籍

'$..book[?(@.price < 10)]'

所有价格低于 10 美元的书籍。(如果路径包含空格,则必须为其加引号)

'$..book[?(@["price"]< 10)]'

所有价格低于 10 美元的书籍

'$..book[?(@.["price"]< 10)]'

所有价格低于 10 美元的书籍

$..book[?(@.price>=10&&@.price<=100)]

所有价格在 10 美元到 100 美元之间(含 10 美元和 100 美元)的书籍

'$..book[?(@.price>=10 && @.price<=100)]'

所有价格在 10 美元到 100 美元之间(含 10 美元和 100 美元)的书籍。(如果路径包含空格,则必须为其加引号)

$..book[?(@.sold==true||@.in-stock==false)]

所有已售出或缺货的书籍

'$..book[?(@.sold == true || @.in-stock == false)]'

所有已售出或缺货的书籍。(如果路径包含空格,则必须为其加引号)

'$.store.book[?(@.["category"] == "fiction")]'

所有小说类书籍

'$.store.book[?(@.["category"] != "fiction")]'

所有非小说类书籍

更多筛选表达式示例:

127.0.0.1:6379> JSON.SET k1 . '{"books": [{"price":5,"sold":true,"in-stock":true,"title":"foo"}, {"price":15,"sold":false,"title":"abc"}]}' OK 127.0.0.1:6379> JSON.GET k1 $.books[?(@.price>1&&@.price<20&&@.in-stock)] "[{\"price\":5,\"sold\":true,\"in-stock\":true,\"title\":\"foo\"}]" 127.0.0.1:6379> JSON.GET k1 '$.books[?(@.price>1 && @.price<20 && @.in-stock)]' "[{\"price\":5,\"sold\":true,\"in-stock\":true,\"title\":\"foo\"}]" 127.0.0.1:6379> JSON.GET k1 '$.books[?((@.price>1 && @.price<20) && (@.sold==false))]' "[{\"price\":15,\"sold\":false,\"title\":\"abc\"}]" 127.0.0.1:6379> JSON.GET k1 '$.books[?(@.title == "abc")]' [{"price":15,"sold":false,"title":"abc"}] 127.0.0.1:6379> JSON.SET k2 . '[1,2,3,4,5]' 127.0.0.1:6379> JSON.GET k2 $.*.[?(@>2)] "[3,4,5]" 127.0.0.1:6379> JSON.GET k2 '$.*.[?(@ > 2)]' "[3,4,5]" 127.0.0.1:6379> JSON.SET k3 . '[true,false,true,false,null,1,2,3,4]' OK 127.0.0.1:6379> JSON.GET k3 $.*.[?(@==true)] "[true,true]" 127.0.0.1:6379> JSON.GET k3 '$.*.[?(@ == true)]' "[true,true]" 127.0.0.1:6379> JSON.GET k3 $.*.[?(@>1)] "[2,3,4]" 127.0.0.1:6379> JSON.GET k3 '$.*.[?(@ > 1)]' "[2,3,4]"

受限的语法

符号/表达式 说明

. 或 []

子运算符

[]

数组下标运算符。索引从 0 开始。

示例

路径 说明

.store.book[0].author

第一本书籍的作者

.store.book[-1].author

最后一本书籍的作者

.address.city

城市名称

["store"]["book"][0]["title"]

第一本书籍的书名

["store"]["book"][-1]["title"]

最后一本书籍的书名

注意

本文档中引用的所有 Goessner 内容均受知识共享许可证的约束。

常见错误前缀

每条错误消息均有一个前缀。以下是常见错误前缀的列表:

Prefix 说明

ERR

一般性错误

LIMIT

超出大小限制错误。例如,超出文档大小限制或嵌套深度限制

NONEXISTENT

键或路径不存在

OUTOFBOUNDARIES

数组索引超出界限

SYNTAXERR

语法错误

WRONGTYPE

错误的值类型

JSON 相关指标

提供了以下 JSON 信息指标:

Info 说明

json_total_memory_bytes

分配给 JSON 对象的总内存

json_num_documents

Redis 中的文档总数

要查询核心指标,请运行 Redis 命令:

info json_core_metrics

MemoryDB 如何与 JSON 交互

以下内容说明了 MemoryDB 如何与 JSON 数据类型交互。

运算符优先顺序

当评估条件表达式以进行筛选时,&& 优先评估,然后评估 ||,这一点在大多数语言中很常见。首先执行括号内的操作。

最大路径嵌套限制行为

MemoryDB 的最大路径嵌套限制为 128。因此,像 $.a.b.c.d... 这样的值只能达到 128 个级别。

处理数字值

JSON 没有针对整数和浮点数的单独数据类型。它们都被称为数字。

当接收 JSON 数字时,以两种格式之一存储该数字。如果该数字适合 64 位有符号整数,则将其转换为该格式;否则,将其存储为字符串。尽量保持两个 JSON 数字(例如 JSON.NUMINCRBY 和 JSON.NUMMULTBY)的算术运算精度。如果两个操作数和结果值适合一个 64 位有符号整数,则执行整数运算。否则,输入操作数将转换为 64 位 IEEE 双精度浮点数,执行算术运算,并将结果转换回字符串。

算术命令 NUMINCRBYNUMMULTBY

  • 如果两个数字都是整数并且结果超出 int64 的范围,则它会自动变成一个双精度浮点数。

  • 如果至少有一个数字是浮点,则结果将是双精度浮点数。

  • 如果结果超出双精度值的范围,则该命令将返回 OVERFLOW 错误。

注意

在 Redis 引擎版本 6.2.6.R2 之前,当在输入时接收 JSON 数字时,它会转换为两种内部二进制表示之一:64 位有符号整数或 64 位 IEEE 双精度浮点。不保留原始字符串及其所有格式。因此,当数字作为 JSON 响应的一部分输出时,它会从内部二进制表示转换为使用通用格式规则的可打印字符串。这些规则可能会导致生成的字符串与收到的字符串不同。

  • 如果两个数字都是整数并且结果超出 int64 的范围,则它会自动变成一个 64 位 IEEE 双精度浮点数。

  • 如果至少有一个数字是浮点,则结果是 64 位 IEEE 双精度浮点数。

  • 如果结果超出 64 位 IEEE 双精度值的范围,则该命令将返回 OVERFLOW 错误。

有关可用命令的详细列表,请参阅 支持的命令

严格语法评估

MemoryDB 不允许使用无效语法的 JSON 路径,即使路径的子集包含有效路径也是如此。这是为了维护我们客户的正确行为。