Модель обработки JSONata
Система типов JSONata
JSONata — надмножество JSON, поэтому её система типов расширяет типы JSON. Как и в функциональных языках, функция здесь — значение первого класса. Поддерживаются: строка, число, логическое значение, null, объект, массив и функция. Все, кроме функции, знакомы по JSON.
Последовательности
JSONata прежде всего язык запросов: выражение пути выбирает ноль, одно или много значений документа. Эти значения любого поддерживаемого типа образуют результирующую последовательность. При объединении подвыражений или передаче их результата в контекст другого выражения последовательности разворачиваются.
- Пустая последовательность не содержит значений: это «ничего» или «нет совпадения». Она не появляется в выводе. Если ей соответствует свойство объекта результата, свойства в объекте не будет.
- Одноэлементная последовательность эквивалентна самому значению и возвращается без внешней структуры.
- Последовательность из нескольких значений выводится как JSON-массив, но внутренне остаётся последовательностью. Массив, выбранный из входного JSON или явно созданный через конструктор массива, остаётся массивом и не подчиняется этим правилам; однако результат выражения, вычисленного в его контексте, будет последовательностью.
- Вложенные последовательности поднимаются на уровень внешней: результирующая последовательность никогда не содержит дочерних последовательностей.
Обработка путей JSONata
Путь JSONata — декларативный функциональный язык. Он функциональный, потому что основан на парадигме map/filter/reduce и функциях высшего порядка; декларативный — потому что компактный синтаксис описывает намерение запроса, а не управляющие конструкции вычисления.
| Этап | Синтаксис | Действие |
|---|---|---|
| Map | seq.expr | Вычисляет правую часть в контексте каждого элемента входной последовательности и разворачивает результаты. |
| Filter | seq[expr] | Оставляет результаты предыдущего этапа, для которых предикат в скобках истинен. |
| Sort | seq^(expr) | Сортирует входную последовательность по критерию в скобках. |
| Index | seq#$var | Привязывает именованную переменную к позиции текущего элемента (нумерация с нуля). |
| Join | seq@$var | Привязывает переменную к текущему элементу; допустим только сразу после Map. |
| Reduce | seq{key: value} | Группирует и агрегирует вход в один объект; допустим только заключительным этапом пути. |
Здесь seq — результат предыдущего этапа. Фильтр имеет приоритет выше Map: books.authors[0] выбирает первого автора каждой книги. У Sort самый низкий приоритет: сортируется весь путь слева. Скобки меняют это правило: (books.authors)[0] выбирает первого автора из всех книг. Скобки также создают область видимости, поэтому переменные @ и #, созданные внутри них, затем недоступны. Эти переменные также выходят из области видимости в конце пути; Reduce завершает текущий путь.