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( )

字符串应该用单引号(')或双引号(")括起来。 在字符串内部,单引号或双引号(取决于用哪个来括起来)和反斜杠(\)需要用反斜杠(\)进行转义。

示例

  1. {
  2. "books": [
  3. {
  4. "category": "reference",
  5. "author": "Nigel Rees",
  6. "title": "Sayings of the Century",
  7. "price": 8.95,
  8. "id": 1
  9. },
  10. {
  11. "category": "fiction",
  12. "author": "Evelyn Waugh",
  13. "title": "Sword of Honour",
  14. "price": 12.99,
  15. "id": 2
  16. },
  17. {
  18. "category": "fiction",
  19. "author": "Herman Melville",
  20. "title": "Moby Dick",
  21. "isbn": "0-553-21311-3",
  22. "price": 8.99,
  23. "id": 3
  24. },
  25. {
  26. "category": "fiction",
  27. "author": "J. R. R. Tolkien",
  28. "title": "The Lord of the Rings",
  29. "isbn": "0-395-19395-8",
  30. "price": 22.99,
  31. "id": 4
  32. }
  33. ],
  34. "services": {
  35. "delivery": {
  36. "servicegroup": 1000,
  37. "description": "Next day delivery in local town",
  38. "active": true,
  39. "price": 5
  40. },
  41. "bookbinding": {
  42. "servicegroup": 1001,
  43. "description": "Printing and assembling book in A5 format",
  44. "active": true,
  45. "price": 154.99
  46. },
  47. "restoration": {
  48. "servicegroup": 1002,
  49. "description": "Various restoration methods",
  50. "active": false,
  51. "methods": [
  52. {
  53. "description": "Chemical cleaning",
  54. "price": 46
  55. },
  56. {
  57. "description": "Pressing pages damaged by moisture",
  58. "price": 24.5
  59. },
  60. {
  61. "description": "Rebinding torn book",
  62. "price": 99.49
  63. }
  64. ]
  65. }
  66. },
  67. "filters": {
  68. "price": 10,
  69. "category": "fiction",
  70. "no filters": "no \"filters\""
  71. },
  72. "closed message": "Store is closed",
  73. "tags": [
  74. "a",
  75. "b",
  76. "c",
  77. "d",
  78. "e"
  79. ]
  80. }
JSONPathTypeResult
$.filters.pricedefinite10
$.filters.categorydefinitefiction
$.filters[‘no filters’]definiteno “filters”
$.filtersdefinite{
“price”: 10,
“category”: “fiction”,
“no filters”: “no \”filters\””
}
$.books[1].titledefiniteSword of Honour
$.books[-1].authordefiniteJ. R. R. Tolkien
$.books.length()definite4
$.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()definite2
$.books[0, 2].titleindefinite[“Moby Dick”, “Sayings of the Century”]
$.books[1][‘author’, “title”]indefinite[“Sword of Honour”, “Evelyn Waugh”]
$..idindefinite[1, 2, 3, 4]
$.services..priceindefinite[154.99, 5, 46, 24.5, 99.49]
$.books[?(@.id == 4 - 0.4 5)].titleindefinite[“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)].titleindefinite[“Sword of Honour”, “The Lord of the Rings”]
$.books[?(!(@.id == 2))].titleindefinite[“Sayings of the Century”, “Moby Dick”, “The Lord of the Rings”]
$.books[?(@.id != 2)].titleindefinite[“Sayings of the Century”, “Moby Dick”, “The Lord of the Rings”]
$.books[?(@.title =~ “ of “)].titleindefinite[“Sayings of the Century”, “Sword of Honour”, “The Lord of the Rings”]
$.books[?(@.price > 12.99)].titleindefinite[“The Lord of the Rings”]
$.books[?(@.author > “Herman Melville”)].titleindefinite[“Sayings of the Century”, “The Lord of the Rings”]
$.books[?(@.price > $.filters.price)].titleindefinite[“Sword of Honour”, “The Lord of the Rings”]
$.books[?(@.category == $.filters.category)].titleindefinite[“Sword of Honour”,”Moby Dick”,”The Lord of the Rings”]
$.books[?(@.category == “fiction” && @.price < 10)].titleindefinite[“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)].descriptionindefinite[“Printing and assembling book in A5 format”, “Rebinding torn book”]
$..id.length()definite4
$.books[?(@.id == 2)].title.first()definiteSword of Honour
$..tags.first().length()definite5

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()definite8.95
$..price.max()definite154.99
$.books[?(@.category == “fiction”)].price.avg()definite14.99
$.books[?(@.category == $.filters.xyz)].titleindefiniteNote: A query without match returns NULL for definite and indefinite paths.
$.services[?(@.active==”true”)].servicegroupindefinite[1001,1000]

Note: Text constants must be used in boolean value comparisons.
$.services[?(@.active==”false”)].servicegroupindefinite[1002]

Note: Text constants must be used in boolean value comparisons.
$.services[?(@.servicegroup==”1002”)]~.first()definiterestoration