JSON数据类型概述 - 亚马逊 ElastiCache

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

JSON数据类型概述

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

术语

租期 描述

JSON文档

指JSON密钥的值。

JSON价值

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

JSON元素

等同于JSON价值。

支持的JSON标准

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

根元素

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

文档大小限制

JSON文档以一种经过优化的格式存储在内部,该格式经过优化,便于快速访问和修改。此格式通常会导致比同一文档的等效序列化表示使用稍多的内存。

单个JSON文档的内存消耗限制为 64 MB,这是内存中数据结构的大小,而不是JSON字符串的大小。您可以使用JSON.DEBUG MEMORY命令检查JSON文档消耗的内存量。

JSON ACLs

  • 与现有的每种数据类型类别(@string、@hash 等)类似,添加了一个新类别 @json,以简化对JSON命令和数据的访问的管理。没有其他现有的 Valkey 或 Redis OSS 命令属于 @json 类别。所有JSON命令都强制执行任何密钥空间或命令限制和权限。

  • 现有五个 Valkey 和 Redis OSS 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 的文档的尝试都将被拒绝,并出现错误。

命令语法

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

表示法:

  • 必需的参数括在尖括号内。例如:<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

Valkey 或 Redis OSS 中的文档总数。

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

info json_core_metrics

如何 ElastiCache 与 Valkey 和 Redis 互动 OSS JSON

以下部分介绍如何 ElastiCache 使用 Valkey 和 Redis 与数据类型进行OSS交互。JSON

运算符优先顺序

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

最大路径嵌套限制行为

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

处理数字值

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

数字的表示形式:

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

算术命令 NUMINCRBYNUMMULTBY

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

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

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

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

直接数组筛选

ElastiCache 使用 Valkey 或 Redis 可以直接OSS过滤数组对象。

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

数组索引行为

ElastiCache 使用 Valkey 或 Redis 时,数OSS组可以同时使用正索引和负索引。对于长度为 5 的数组,0 将查询第一个元素,1 将查询第二个元素,依此类推。负数从数组的末尾开始,因此 -1 将查询第五个元素,-2 将查询第四个元素,依此类推。

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

严格语法评估

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