В этом разделе приведены сведения о поддерживаемом функционале 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() | Возвращает поле price первого объекта с именем «Object». |
$[?(@.name == 'Object')].history.first().length() | Возвращает количество элементов массива history первого объекта с именем «Object». |
$[?(@.price > 10)].length() | Возвращает количество объектов с price больше чем 10. |
Смотрите также: Экранирование специальных символов из значений LLD макросов в JSONPath.
| Сегмент | Описание |
|---|---|
<имя> | Соответствие свойству объекта по имени. |
* | Соответствие всем свойствам объекта. |
['<имя>'] | Соответствие свойству объекта по имени. |
['<имя>', '<имя>', ...] | Соответствие свойству объекта по любому из перечисленных имён. |
[<индекс>] | Соответствие элементу массива по его индексу. |
[<число>, <число>, ...] | Соответствие элементу массива по любому из перечисленных индексов. |
[*] | Соответствие всем свойствам объекта или элементам массива. |
[<начало>:<конец>] | Соответствие элементам массива по заданному диапазону: <начало> — первый индекс соответствия (включительно). Если не указан, соответствует всем элементам с самого начала. В случае отрицательного значения указывает начальное смещение от конца массива. <конец> — последний индекс соответствия (не включая). Если не указан, соответствует всем элементам массива до самого конца. В случае отрицательного значения указывает начальное смещение от конца массива. |
[?(<выражение>)] | Соответствие объектов / элементов массива с применением выражения фильтра. |
Чтобы найти соответствующий сегмент, игнорируя его происхождение (отсоединённый сегмент), его необходимо указывать с префиксом '..', например $..name или $..['name'] вернёт значения всех свойств «name».
Соответствующие имена элементов можно извлечь, добавив суффикс ~ к JSONPath. Он возвращает имя соответствующего объекта или индекс в строковом формате соответствующего элемента массива. Формат вывода следует тем же самым правилам, что и остальные запросы JSONPath — результаты определённого пути возвращаются «как есть», а результаты неопределённого пути возвращаются в виде массива. Однако, нет особого смысла извлекать имя соответствующего элемента определённого пути — оно и так уже известно.
Выражение фильтра является арифметическим выражением в инфиксной нотации.
Поддерживаемые операнды:
| Операнд | Описание | Пример |
|---|---|---|
"<текст>"'<text>' | Текстовая константа. | 'value: \'1\'' "value: '1'" |
<число> | Числовая константа, поддерживая научное представление. | 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 принимаются числовые значения в кавычках. Это означает, что значения преобразуются из строкового типа в числовой, если требуется агрегирование.
Несовместимые входные данные повлекут ошибку в функции.
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": "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 | определённый | 10 | |
$.filters.category | определённый | fiction | |
$.filters['no filters'] | определённый | no "filters" | |
$.filters | определённый | { "price": 10, "category": "fiction", "no filters": "no \"filters\"" } | |
$.books[1].title | определённый | Sword of Honour | |
$.books[-1].author | определённый | J. R. R. Tolkien | |
$.books.length() | определённый | 4 | |
$.tags[:] | неопределённый | ["a", "b", "c", "d", "e" ] | |
$.tags[2:] | неопределённый | ["c", "d", "e" ] | |
$.tags[:3] | неопределённый | ["a", "b", "c"] | |
$.tags[1:4] | неопределённый | ["b", "c", "d"] | |
$.tags[-2:] | неопределённый | ["d", "e"] | |
$.tags[:-3] | неопределённый | ["a", "b"] | |
$.tags[:-3].length() | определённый | 2 | |
$.books[0, 2].title | неопределённый | ["Sayings of the Century", "Moby Dick"] | |
$.books[1]['author', "title"] | неопределённый | ["Evelyn Waugh", "Sword of Honour"] | |
$..id | неопределённый | [1, 2, 3, 4] | |
$.services..price | неопределённый | [5, 154.99, 46, 24.5, 99.49] | |
$.books[?(@.id == 4 - 0.4 * 5)].title | неопределённый | ["Sword of Honour"] | Этот запрос показывает, что в запросах можно использовать математические операции. Конечно, этот запрос можно упростить до $.books[?(@.id == 2)].title |
$.books[?(@.id == 2 \|\| @.id == 4)].title | неопределённый | ["Sword of Honour", "The Lord of the Rings"] | |
$.books[?(!(@.id == 2))].title | неопределённый | ["Sayings of the Century", "Moby Dick", "The Lord of the Rings"] | |
$.books[?(@.id != 2)].title | неопределённый | ["Sayings of the Century", "Moby Dick", "The Lord of the Rings"] | |
$.books[?(@.title =~ " of ")].title | неопределённый | ["Sayings of the Century", "Sword of Honour", "The Lord of the Rings"] | |
$.books[?(@.price > 12.99)].title | неопределённый | ["The Lord of the Rings"] | |
$.books[?(@.author > "Herman Melville")].title | неопределённый | ["Sayings of the Century", "The Lord of the Rings"] | |
$.books[?(@.price > $.filters.price)].title | неопределённый | ["Sword of Honour", "The Lord of the Rings"] | |
$.books[?(@.category == $.filters.category)].title | неопределённый | ["Sword of Honour","Moby Dick","The Lord of the Rings"] | |
$.books[?(@.category == "fiction" && @.price < 10)].title | неопределённый | ["Moby Dick"] | |
$..[?(@.id)] | неопределённый | [ { "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 | неопределённый | '["Printing and assembling book in A5 format", "Rebinding torn book"] | |
$..id.length() | определённый | 4 | |
$.books[?(@.id == 2)].title.first() | определённый | Sword of Honour | |
$..tags.first().length() | определённый | 5 | $..tags - неопределённый путь, поэтому он вернёт массив соответствующих элементов - [["a", "b", "c", "d", "e" ]], first() вернёт первый элемент - ["a", "b", "c", "d", "e" ] и, наконец, length() вычислит его размер - 5. |
$.books[*].price.min() | определённый | 8.95 | |
$..price.max() | определённый | 154.99 | |
$.books[?(@.category == "fiction")].price.avg() | определённый | 14.99 | |
$.books[?(@.category == $.filters.xyz)].title | неопределённый | Запрос без совпадения вернёт NULL по определённому и неопределённому путям. | |
$.services[?(@.active=="true")].servicegroup | неопределённый | [1000,1001] | В сравнениях логических значений необходимо использовать текстовые константы. |
$.services[?(@.active=="false")].servicegroup | неопределённый | [1002] | В сравнениях логических значений необходимо использовать текстовые константы. |
$.services[?(@.servicegroup=="1002")]~.first() | определенный | restoration |