这是原厂英文文档的翻译页面. 欢迎帮助我们 完善文档.
2022 Zabbix中国峰会
2022 Zabbix中国峰会

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数组元素的个数。
$[?(@.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> 来自输入文档根节点的JSONPath引用的值; 只支持明确的路径。 $.object.name
<以@开头的jsonpath> 当前对象/元素的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 聚合函数接受带引号的数值。 这意味着如果需要聚合,则将值从字符串类型转换为数字。

不兼容的输入会导致函数产生错误。

输出值

JSONPaths 可以分为确定路径和不确定路径。 确定路径只能返回 null 或单个匹配项。 不定路径可以返回多个匹配项,基本上是带有分离的、多个名称/索引列表、数组切片或表达式段的 JSONPath。 但是,当使用函数时,JSONPath 变得明确,因为函数总是输出单个值。

确定路径返回它所引用的对象/数组/值,而不定路径返回匹配的对象/数组/值的数组。

空格

空格(空格、制表符)可以在括号符号段和表达式中自由使用,例如,$[ '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": "Checmical 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 类型 结果 注释
$.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 ["Sayings of the Century", "Moby Dick"]
$.books[1]['author', "title"] indefinite ["Evelyn Waugh", "Sword of Honour"]
$..id indefinite [1, 2, 3, 4]
$.services..price indefinite [5, 154.99, 46, 24.5, 99.49]
$.books[?(@.id == 4 - 0.4 * 5)].title indefinite ["Sword of Honour"] 此查询表明可以在查询中使用算术运算。当然这个查询可以简化为 $.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"]
$..[?(@.id)] indefinite [
{
"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..[?(@.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 是不明确的路径,所以它返回一个匹配元素的数组 - [["a", "b", "c", "d", "e" ]], first() 返回第一个元素 - ["a", "b", "c", "d", "e" ] 和最后ength() 计算它的长度 - 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 不匹配的查询对于明确和不明确的路径返回 NULL。
$.services[?(@.active=="true")].servicegroup indefinite [1000,1001] 在布尔值比较中必须使用文本常量。
$.services[?(@.active=="false")].servicegroup indefinite [1002] 在布尔值比较中必须使用文本常量。
$.services[?(@.servicegroup=="1002")]~.first() definite 恢复