4 JSONPath 功能
概述
本部分提供监控项值预处理步骤中支持的JSONPath功能的详细信息。
JSONPath由用点分隔的段组成。 段可以是一个简单的词,如 JSON 值名称、*
,也可以是括在方括号 [
]
中的更复杂的构造。 括号段前的分隔点是可选的,可以省略。 例如:
路径 | 描述 |
---|---|
$.object.name | 返回object.name的内容。 |
$.object[‘name’] | 返回object.name的内容。 |
$.object.[‘name’] | 返回object.name的内容。 |
$[“object”][‘name’] | 返回object.name的内容。 |
$.[‘object’].[“name”] | 返回object.name的内容。 |
$.object.history.length() | 返回object.history数组元素的个数。 |
$[?(@.name == ‘Object’)].price.first() | 返回第一个名为’Object’的对象的价格字段。 |
$[?(@.name == ‘Object’)].history.first().length() | 返回第一个名为’Object’的对象的历史数组元素个数。 |
$[?(@.price > 10)].length() | 返回price大于10的对象个数。 |
参考: 从 JSONPath 中的 LLD 宏值中转义特殊字符.
支持的段
段 | 描述 |
---|---|
<name> | 按名称匹配对象属性。 |
| 匹配所有对象属性。 |
[‘<name>’] | 按名称匹配对象属性。 |
[‘<name>’, ‘<name>’, …] | 通过任何列出的名称匹配对象属性。 |
[<index>] | 按索引匹配数组元素。 |
[<number>, <number>, …] | 通过任何列出的索引匹配数组元素。 |
[] | 匹配所有对象属性或数组元素。 |
[<start>:<end>] | 按定义的范围匹配数组元素: <start> - 要匹配的第一个索引(包括)。 如果未指定,则匹配从头开始的所有数组元素。 如果为负数,则指定从数组末尾开始的偏移量。 <end> - 要匹配的最后一个索引(不包括)。 如果未指定,则匹配所有数组元素到最后。 如果为负数,则指定从数组末尾开始的偏移量。 |
[?(<表达式>)] | 通过应用过滤表达式匹配对象/数组元素。 |
要查找忽略其根节点的匹配段(单独的段),它必须以 ‘..’ 为前缀,例如 $..name
或 $..['name']
返回所有 ‘name’ 属性的值。
可以通过在 JSONPath 中添加 ~
后缀来提取匹配的元素名称。 它返回匹配对象的名称或匹配数组项的字符串格式的索引。 输出格式遵循与其他 JSONPath 查询相同的规则 - 确定路径结果按“原样”返回,不确定路径结果以数组形式返回。 但是,提取与明确路径匹配的元素的名称并没有多大意义——它是已知的。
过滤表达式
过滤表达式是一个中缀表示法中的算术表达式。
支持的操作数:
操作数 | 描述 |
---|---|
“<text>” ‘<text>’ | 文本常量。 示例: ‘value: \‘1\‘’ “value: ‘1’” |
<number> | 支持科学计数法的数值常量。 示例: 123 |
<jsonpath starting with $> | 从输入文档根节点引用的 JSONPath 所指的值;仅支持确定的路径。 示例: $.object.name |
<jsonpath starting with @> | 从当前对象/元素引用的 JSONPath 所指的值;仅支持确定的路径。 示例: @.name |
支持的运算符:
运算符 | 类型 | 描述 | 结果 |
---|---|---|---|
- | 二元 | 减法 | 数值 |
+ | 二元 | 加法 | 数值 |
/ | 二元 | 除法 | 数值 |
* | 二元 | 乘法 | 数值 |
== | 二元 | 相等性 | 布尔值(1/0) |
!= | 二元 | 不相等性 | 布尔值(1/0) |
< | 二元 | 小于 | 布尔值(1/0) |
<= | 二元 | 小于等于 | 布尔值(1/0) |
> | 二元 | 大于 | 布尔值(1/0) |
>= | 二元 | 大于等于 | 布尔值(1/0) |
=~ | 二元 | 匹配正则表达式 | 布尔值(1/0) |
! | 一元 | 布尔非 | 布尔值(1/0) |
|| | 二元 | 布尔或 | 布尔值(1/0) |
&& | 二元 | 布尔与 | 布尔值(1/0) |
函数
函数可以用在 JSONPath 的末尾。 如果前面的函数返回后面函数接受的值,则可以链接多个函数。
支持的函数:
函数 | 描述 | 输入 | 输出 |
---|---|---|---|
avg | 输入数组中数字的平均值。 | 数字数组。 | 数字。 |
min | 输入数组中数字的最小值。 | 数字数组。 | 数字。 |
max | 输入数组中数字的最大值。 | 数字数组。 | 数字。 |
sum | 输入数组中数字的总和。 | 数字数组。 | 数字。 |
length | 输入数组中的元素数量。 | 数组。 | 数字。 |
first | 第一个数组元素。 | 数组。 | 取决于输入数组内容的 JSON 构造(对象、数组、值)。 |
JSONPath 聚合函数接受带引号的数值。 这意味着如果需要聚合,则将值从字符串类型转换为数字。
不兼容的输入会导致函数产生错误。
输出值
JSONPath 可以分为确定路径和不确定路径。 确定路径只能返回 null 或单个匹配项。 不确定路径可以返回多个匹配项:具有分离的、多个名称/索引列表、数组切片或表达式段的 JSONPath。 但是,当使用函数时,JSONPath 变为确定,因为函数始终输出单个值。
确定路径返回它引用的对象/数组/值。 相反,不确定路径返回匹配对象/数组/值的数组。
由于内部优化方法的原因,JSONPath 查询结果中的属性顺序可能与原始 JSON 属性顺序不一致。 例如,JSONPath $.books[1]["author", "title"]
可能返回 ["title", "author"]
。 如果保留原始属性顺序很重要,则应考虑使用替代的查询后处理方法。
路径格式化规则
在方括号表示法的段和表达式中可以使用空格(空格、制表符),例如:$[ 'a' ][ 0 ][ ?( $.b == 'c' ) ][ : -1 ].first( )
。
字符串应该用单引号('
)或双引号("
)括起来。 在字符串内部,单引号或双引号(取决于用哪个来括起来)和反斜杠(\
)需要用反斜杠(\
)进行转义。
示例
{
"books": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95,
"id": 1
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99,
"id": 2
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99,
"id": 3
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99,
"id": 4
}
],
"services": {
"delivery": {
"servicegroup": 1000,
"description": "Next day delivery in local town",
"active": true,
"price": 5
},
"bookbinding": {
"servicegroup": 1001,
"description": "Printing and assembling book in A5 format",
"active": true,
"price": 154.99
},
"restoration": {
"servicegroup": 1002,
"description": "Various restoration methods",
"active": false,
"methods": [
{
"description": "Chemical cleaning",
"price": 46
},
{
"description": "Pressing pages damaged by moisture",
"price": 24.5
},
{
"description": "Rebinding torn book",
"price": 99.49
}
]
}
},
"filters": {
"price": 10,
"category": "fiction",
"no filters": "no \"filters\""
},
"closed message": "Store is closed",
"tags": [
"a",
"b",
"c",
"d",
"e"
]
}
JSONPath | Type | Result |
---|---|---|
$.filters.price | definite | 10 |
$.filters.category | definite | fiction |
$.filters[‘no filters’] | definite | no “filters” |
$.filters | definite | { “price”: 10, “category”: “fiction”, “no filters”: “no \”filters\”” } |
$.books[1].title | definite | Sword of Honour |
$.books[-1].author | definite | J. R. R. Tolkien |
$.books.length() | definite | 4 |
$.tags[:] | indefinite | [“a”, “b”, “c”, “d”, “e” ] |
$.tags[2:] | indefinite | [“c”, “d”, “e” ] |
$.tags[:3] | indefinite | [“a”, “b”, “c”] |
$.tags[1:4] | indefinite | [“b”, “c”, “d”] |
$.tags[-2:] | indefinite | [“d”, “e”] |
$.tags[:-3] | indefinite | [“a”, “b”] |
$.tags[:-3].length() | definite | 2 |
$.books[0, 2].title | indefinite | [“Moby Dick”, “Sayings of the Century”] |
$.books[1][‘author’, “title”] | indefinite | [“Sword of Honour”, “Evelyn Waugh”] |
$..id | indefinite | [1, 2, 3, 4] |
$.services..price | indefinite | [154.99, 5, 46, 24.5, 99.49] |
$.books[?(@.id == 4 - 0.4 5)].title | indefinite | [“Sword of Honour”] Note: This query shows that arithmetical operations can be used in queries; it can be simplified to $.books[?(@.id == 2)].title |
$.books[?(@.id == 2 || @.id == 4)].title | indefinite | [“Sword of Honour”, “The Lord of the Rings”] |
$.books[?(!(@.id == 2))].title | indefinite | [“Sayings of the Century”, “Moby Dick”, “The Lord of the Rings”] |
$.books[?(@.id != 2)].title | indefinite | [“Sayings of the Century”, “Moby Dick”, “The Lord of the Rings”] |
$.books[?(@.title =~ “ of “)].title | indefinite | [“Sayings of the Century”, “Sword of Honour”, “The Lord of the Rings”] |
$.books[?(@.price > 12.99)].title | indefinite | [“The Lord of the Rings”] |
$.books[?(@.author > “Herman Melville”)].title | indefinite | [“Sayings of the Century”, “The Lord of the Rings”] |
$.books[?(@.price > $.filters.price)].title | indefinite | [“Sword of Honour”, “The Lord of the Rings”] |
$.books[?(@.category == $.filters.category)].title | indefinite | [“Sword of Honour”,”Moby Dick”,”The Lord of the Rings”] |
$.books[?(@.category == “fiction” && @.price < 10)].title | indefinite | [“Moby Dick”] |
$..[?(@.id)] | indefinite | [ { “price”: 8.95, “id”: 1, “category”: “reference”, “author”: “Nigel Rees”, “title”: “Sayings of the Century” }, { “price”: 12.99, “id”: 2, “category”: “fiction”, “author”: “Evelyn Waugh”, “title”: “Sword of Honour” }, { “price”: 8.99, “id”: 3, “category”: “fiction”, “author”: “Herman Melville”, “title”: “Moby Dick”, “isbn”: “0-553-21311-3” }, { “price”: 22.99, “id”: 4, “category”: “fiction”, “author”: “J. R. R. Tolkien”, “title”: “The Lord of the Rings”, “isbn”: “0-395-19395-8” } ] |
$.services..[?(@.price > 50)].description | indefinite | [“Printing and assembling book in A5 format”, “Rebinding torn book”] |
$..id.length() | definite | 4 |
$.books[?(@.id == 2)].title.first() | definite | Sword of Honour |
$..tags.first().length() | definite | 5 Note: $..tags is an indefinite path, so it returns an array of matched elements, i.e., [[“a”, “b”, “c”, “d”, “e” ]] ; first() returns the first element, i.e., [“a”, “b”, “c”, “d”, “e”] ; length() calculates the length of the element, i.e.,5 . |
$.books[].price.min() | definite | 8.95 |
$..price.max() | definite | 154.99 |
$.books[?(@.category == “fiction”)].price.avg() | definite | 14.99 |
$.books[?(@.category == $.filters.xyz)].title | indefinite | Note: A query without match returns NULL for definite and indefinite paths. |
$.services[?(@.active==”true”)].servicegroup | indefinite | [1001,1000] Note: Text constants must be used in boolean value comparisons. |
$.services[?(@.active==”false”)].servicegroup | indefinite | [1002] Note: Text constants must be used in boolean value comparisons. |
$.services[?(@.servicegroup==”1002”)]~.first() | definite | restoration |