3 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 array元素的数量。
$[?(@.name == 'Object')].price.first() 返回名称为'object'的第一个object的price字段。
$[?(@.name == 'Object')].history.first().length() 返回名称为'object'的第一个object的history array元素数量。
$[?(@.price > 10)].length() 返回price大于10的objects数量。

另请参阅:Escaping special characters from LLD macro values in JSONPath

支持的片段

片段 描述
<name> 按名称匹配object属性。
* 匹配所有object属性。
['<name>'] 按名称匹配object属性。
['<name>', '<name>', ...] 按列出的任意名称匹配object属性。
[<index>] 按索引匹配array元素。
[<number>, <number>, ...] 按列出的任意索引匹配array元素。
[*] 匹配所有object属性或array元素。
[<start>:<end>] 按定义范围匹配array元素:
<起始> - 要匹配的第一个索引(包含)。如果未指定,则从开头匹配所有array元素。如果为负值,则指定从array末尾的起始偏移量。
<结束> - 要匹配的最后一个索引(不包含)。如果未指定,则匹配到末尾的所有array元素。如果为负值,则指定从array末尾的起始偏移量。
[?(<expression>)] 通过应用过滤表达式匹配objects/array元素。

要忽略祖先关系(分离片段)查找匹配片段, 必须以'..'为前缀,例如$..name$..['name'] 返回所有'名称'属性的值。

可以通过在JSONPath后添加~后缀来提取匹配的元素名称。 它返回匹配的object名称或匹配的array监控项的string格式索引。 输出格式遵循与其他JSONPathqueries相同的规则 - 确定路径结果 按原样返回,不确定路径结果以array形式返回。 然而提取确定路径匹配元素的名称没有太大意义 - 它已经是已知的。

过滤表达式

过滤表达式是一个中缀表示法的算术表达式。

支持的运算数:

运算数 描述 示例
"<text>"
'<text>'
文本常量。 'value: \'1\''
"value: '1'"
<number> 支持科学计数法的数字常量。 123
<jsonpath starting with $> 从输入文档根节点引用的JSONPath值;仅支持确定路径。 $.object.name
<jsonpath starting with @> 从当前object/元素引用的JSONPath值;仅支持确定路径。 @.name

支持的运算符:

运算符 类型 描述 结果
- binary 减法。 数字。
+ binary 加法。 数字。
/ binary 除法。 数字。
* binary 乘法。 数字。
== binary 等于。 boolean (1或0)。
!= binary 不等于。 boolean (1或0)。
< binary 小于。 boolean (1或0)。
<= binary 小于或等于。 boolean (1或0)。
> binary 大于。 boolean (1或0)。
>= binary 大于或等于。 boolean (1或0)。
=~ binary 匹配正则表达式。 boolean (1或0)。
! unary boolean 非。 boolean (1或0)。
|| binary boolean 或。 boolean (1或0)。
&& binary boolean 与。 boolean (1或0)。

函数

函数可以用于JSONPath的末尾。如果前一个函数返回的值能被后续函数接受, 则可以链式调用多个函数。

支持的函数:

函数 描述 输入 输出
avg 输入array中数字的平均值。 数字的array。 数字。
min 输入array中数字的最小值。 数字的array。 数字。
max 输入array中数字的最大值。 数字的array。 数字。
sum 输入array中数字的总和。 数字的array。 数字。
length 输入array中的元素数量。 array。 数字。
first 第一个array元素。 array。 根据输入array内容返回JSON结构(object、array或值)。

JSONPath聚合函数接受带引号的数值。 这意味着如果需要聚合,值会从string类型转换为数字类型。

不兼容的输入将导致函数返回generate错误。

输出值

JSON路径可分为确定路径和不确定路径。确定路径只能返回null或单一匹配项。不确定路径可返回多个匹配项,主要指包含通配符、多重名称/索引列表、array切片或表达式段的JSON路径。但使用函数时JSON路径会转为确定路径,因为函数始终输出单一值。

确定路径返回其引用的object/array/值,而不确定路径返回匹配objects/数组/值的array集合。

由于内部优化方法,JSONPath query结果的属性顺序可能与原始JSON属性顺序不一致。 例如,JSONPath $.books[1]["author", "title"]可能返回["title", "author"]。 若需保持原始属性顺序,应考虑采用query后处理的替代方案。

空白字符

在方括号表示法片段和表达式中可以自由使用空白字符(空格、制表符),例如: $[ '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"
         ]
       }
JSON路径 类型 结果 说明
$.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"] 此query表明算术运算可用于queries。当然这个query可以简化为$.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 $..tags是不定路径,因此返回匹配元素的array - [["a", "b", "c", "d", "e" ]], first()返回第一个元素 - ["a", "b", "c", "d", "e" ],最后length()计算其长度 - 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 无匹配的query对于确定和不确定路径返回NULL。
$.services[?(@.active=="true")].servicegroup indefinite [1001,1000] 文本常量必须用于boolean值比较。
$.services[?(@.active=="false")].servicegroup indefinite [1002] 文本常量必须用于boolean值比较。
$.services[?(@.servicegroup=="1002")]~.first() definite restoration