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

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

Redis JSON 数据类型概述

ElastiCache for Redis 支持许多用于处理 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

  • 与现有的每数据类型类别(@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 ...]

路径语法

Redis JSON 支持两种路径语法:

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

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

注意

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

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

增强的语法

符号/表达式 描述

$

根元素。

. 或 []

子运算符。

..

递归下降。

*

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

[]

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

[,]

联合运算符。

[start:end:step]

数组 Slice 运算符。

?()

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

()

筛选表达式。

@

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

==

等于,用于筛选表达式。

!=

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

>

大于,用于筛选表达式。

>=

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

<

小于,用于筛选表达式。

<=

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

&&

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

||

L逻辑 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 信息指标:

信息 描述

json_total_memory_bytes

分配给 JSON 对象的总内存。

json_num_documents

Redis 中的文档总数。

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

info json_core_metrics

ElastiCache for Redis 如何与 JSON 交互

以下部分介绍了 ElastiCache for Redis 如何与 JSON 数据类型交互。

运算符优先顺序

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

最大路径嵌套限制行为

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

处理数字值

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

数字的表示形式:

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

算术命令 NUMINCRBYNUMMULTBY

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

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

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

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

直接数组筛选

ElastiCache for Redis 可直接筛选数组对象。

对于像 [0,1,2,3,4,5,6] 这样的数据和像 $[?(@<4)] 这样的路径查询,或者像 {"my_key":[0,1,2,3,4,5,6]} 这样的数据和像 $.my_key[?(@<4)] 这样的路径查询,在这两种情况下,ElastiCache for Redis 都会返回 [1,2,3]。

数组索引行为

ElastiCache for Redis 允许数组的正索引和负索引。对于长度为 5 的数组,0 将查询第一个元素,1 将查询第二个元素,依此类推。负数从数组的末尾开始,因此 -1 将查询第五个元素,-2 将查询第四个元素,依此类推。

为确保客户行为可预测,ElastiCache for Redis 不会向下或向上舍入数组索引,因此如果您有一个长度为 5 的数组,则调用索引 5 及更高或 -6 及更低将不会产生结果。

严格语法评估

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