JSONata - це мова запитів і перетворень даних JSON. Іншими словами це мова яка вказує як з вхідного JSON зробити вихідний JSON.
Для маніпулювання та об'єднання відібраних даних передбачено набір вбудованих операторів і функцій, а результати запитів можуть бути відформатовані в будь-яку вихідну структуру JSON, використовуючи звичний JSON-об'єкт і синтаксис масиву. У поєднанні з можливістю створення функцій, визначених користувачем, можна розробити додаткові вирази для вирішення будь-яких JSON-запитів і завдань трансформації.
З загальною документацією по JSONata можна ознайомитися на сайті http://docs.jsonata.org. У цьому розділі наведено деякі вирізки з цієї документації та напрацювання з інших джерел відносно використання в Node-RED. Перевірити загальні вирази JSONata можна на прикладі - http://try.jsonata.org/
JSONata використовується в багатьох вузлах Node-RED. У якості вхідних даних для JSONata є змінна повідомлення msg
, яка розглядається як вхідний документ JSON. Тому до властивостей об'єкта msg
доступаються безпосередньо через імена, наприклад msg.payload
доступний просто як payload
. Наприклад, у наступному прикладі у вихідний msg.payload
записується значення вхідного msg.payload
збільшеного на 1.
JSONata проводить послідовні розрахунки відповідно до вказаного виразу. Після кожного розрахунку результат знаходиться в певній контекстній змінній (називатимо розрахунковий контекст), який можна використовувати в наступних розрахунках. Звернутися до контексту можна через знак $
. Перед початком розрахунків в контексті знаходиться вхідний документ, тобто msg
, тому звертатись до нього можна через $
. Тобто, якщо потрібно отримати доступ до всього об'єкту msg
на верхньому рівні виразу, можна використовувати змінну $
. Наприклад $._msgid
поверне унікальний ідентифікатор повідомлення. Якщо звертання йде всередині розрахунку, то розрахунковий контекст буде містити проміжні результати, тому при необхідності оцінювання вхідного документу до нього звертаються через подвійний "долар" $$
З символу $
починаються також усі функції JSONata та змінні користувача. Останні використовуються тоді, коли є необхідність писати не просто вирази а підпрограми на мові JSONata. Див. Програмні конструкції.
У розрахунках можна також використовувати літеральні константи у форматі JavaScript, значення глобального контексту та контексту потоку, значення змінної середовища та комбінацію всього перерахованого.
Аналогічно як Java Script через крапку можна доступатися до полів властивостей будь якого рівня вкладеності, а через []
до індексу масиву. Однак в JSONata квадратні дужки використовуються також для позначення умови пошуку (предикату).
Якщо результат треба перетворити в інший вигляд, використовуються конструктори масивів ([]
) та об'єктів ({}
). Так наступне повідомлення сформує обєкт з двома полями, в одне запише payload
вхідного повідомлення, а в інше - topic
.
{"value" : payload , "name" : topic }
А у цьому прикладі сформується масив:
[payload , topic]
Доступ до контекстів потоку та глобального контексту можна робити через відповідні функції. Доступ до глобального контексту відбувається через вбудовану у Node-RED JSONata функцію $globalContext()
в якій вказується назва змінної та за необхідності сховище (другим аргументом). Наприклад, наступний приклад доступається до змінної глобального контексту з іменем 'globalVariableName'.
Аналогічно попередній, функція $flowContext()
доступається до контексту потоку.
Для рядків у JSONata можна використовувати оператор конкатенації &
. Наприклад у наступному прикладі якщо вхідний msg.payload=23
а msg.topic='Temperature'
то вихідний msg.payload
дорівнюватиме Temperature = 23
.
Числові літетерали та вирази можуть бути використані в розрахунках результатів з використанням звичайних математичних операторів:
+
додавання-
віднімання*
множення/
ділення%
остача від ділення..
(Range) означення діпазону
На наступному прикладі на виході msg.payload
формується масив елементів зі значеннями від 1 до 100.
Можна використовувати оператори порівняння двох значень, які повертають логічні значення true
або false
:
=
дорівнює!=
не дорівнює<
менше ніж<=
менше ніж чи дорівнює>
більше ніж>=
більше або дорівнює ніжin
значення міститься в масиві
Для логічного об'єднання булевих результатів використовуються оператори and
та or
. Зверніть увагу, що булеве not
підтримується як окрема функція ($not), а не як оператор.
Ось ще кілька прикладів:
[1..3, 7..9] => [1, 2, 3, 7, 8, 9]
[1..$count(Items)].("Item " & $) => ["Item 1","Item 2","Item 3"]
[1..5].($*$) => [1, 4, 9, 16, 25]
Оператор | Пояснення | Приклад |
---|---|---|
. (Map) |
Вираз оцінюється для отримання масиву значень. Якщо це буде одне значення, воно трактується як еквівалент масиву, що містить це єдине значення. Якщо порожній масив, то результат вираження оператора - це nothing For each value in the LHS array in turn: The value is known as the context and is used as the basis for any relative path expression on the RHS. It is also accessible in the RHS expression using the $ symbol. The RHS expression is evaluated to produce a value or array of values (or nothing). These values are appended to a combined array of results for the operator as a whole.Для кожного значення в розрахованому масиві: Значення відоме як контекст і використовується як основа для будь-якого відносного вираження контуру на RHS. Він також доступний у виразі RHS, використовуючи символ $ . Експресія RHS оцінюється для отримання значення або масиву значень (або нічого). Ці значення додаються до комбінованого масиву результатів для оператора в ціломуThe combined result of the operator is returned. |
|
[ ... ] (Filter) |
||
^( ... ) (Order-by) |
||
{ ... } (Reduce) |
||
* (Wildcard) |
||
** (Descendants) |
||
% (Parent) |
||
# (Positional variable binding) |
||
@ (Context variable binding) |
$env
- зчитує змінну середовища з вказаним іменем$flowContext
- доступається до контексту потоку$globalContext
- доступається до глобального контексту$clone
- клонує об'єкт