В данном разделе описываются:
функции и операторы для обработки и создания данных JSON
язык путей SQL/JSON
функции запросов SQL/JSON
Для обеспечения встроенной поддержки типов данных JSON в среде языка SQL, Digital Q.DataBase реализует модель данных SQL/JSON. Данная модель представляет собой последовательности элементов. Каждый элемент может содержать скалярные значения языка SQL, включая дополнительное значение SQL/JSON null, а также составные структуры данных, использующие массивы и объекты JSON. Данная модель является формализацией модели данных, неявно описанной в спецификации JSON RFC 7159.
Инструменты SQL/JSON позволяют обрабатывать данные в формате JSON совместно с обычными данными на языке SQL с поддержкой транзакций, включая:
загрузку данных JSON в базу данных и их хранение в обычных столбцах языка SQL в виде символьных или двоичных строк.
Формирование объектов и массивов JSON из реляционных данных.
Выполнение запросов к данным JSON с использованием функций запросов SQL/JSON и выражений языка путей SQL/JSON.
Для получения дополнительных сведений о стандарте SQL/JSON см. [sqltr-19075-6]. Подробные сведения о типах JSON, поддерживаемых в Digital Q.DataBase, см. Раздел 2.5.14.
Таблица 2.6.45 приведены операторы,
доступные для использования с типами данных JSON (см. Раздел 2.5.14).
Кроме того, обычные операторы сравнения, указанные в Таблица 2.6.1 доступны для типа
jsonb, но не для типа json. Операторы сравнения следуют правилам упорядочивания для операций B-дерева, описанным в
Раздел 2.5.14.4.
См. также Раздел 2.6.21 описание агрегатной
функции json_agg которая агрегирует значения записей в формате JSON, агрегатной функции
json_object_agg которая объединяет пары значений
в объект JSON, и их jsonb эквивалентов,
jsonb_agg и jsonb_object_agg.
Таблица 2.6.45. json и jsonb Операторы
Оператор Описание Примеры |
|---|
Извлекает
|
Извлекает поле JSON-объекта по заданному ключу.
|
Извлекает
|
Извлекает поле JSON-объекта по заданному ключу в виде текстовой строки,
|
Извлекает вложенный JSON-объект по указанному пути, в котором элементами пути могут выступать ключи полей или индексы массива.
|
Данный оператор извлекает вложенный объект JSON по указанному пути как
|
Операторы извлечения поля, элемента или пути возвращают значение NULL вместо генерации ошибки, если входные данные JSON не имеют структуры, соответствующей условиям запроса; например, если указанный ключ или элемент массива отсутствует.
Существуют также дополнительные операторы, предназначенные только для jsonb, как показано
в Таблица 2.6.46.
Раздел 2.5.14.4
описывает способы применения данных операторов для обеспечения эффективного поиска в индексированных
jsonb данных.
Таблица 2.6.46. Дополнительные jsonb Операторы
Оператор Описание Примеры |
|---|
Содержит ли первое значение JSON в себе второе значение? (См. Раздел 2.5.14.3 подробные сведения о проверке на включение приведены далее.)
|
Входит ли первое значение JSON в состав второго значения?
|
Присутствует ли текстовая строка в качестве ключа верхнего уровня или элемента массива внутри значение JSON?
|
Присутствует ли любая из строк текстового массива в качестве ключа верхнего уровня или элемента массива?
|
Присутствуют ли все строки текстового массива в качестве ключей верхнего уровня или элемента массива?
|
Выполняет конкатенацию двух
Чтобы добавить массив в другой массив в качестве одного элемента, его необходимо обернуть в дополнительный массив, например:
|
Удаляет ключ (и соответствующее ему значение) из объекта JSON или совпадающие строковые значения из массива JSON.
|
Операция удаляет из левого операнда все соответствующие ключи или элементы массива.
|
Удаляет элемент массива с указанным индексом (отрицательные целые числа отсчитываются от конца). Если значение JSON не является массивом, возникает ошибка.
|
Удаляет поле или элемент массива по заданному пути, элементами которого могут быть ключи полей или индексы массива.
|
Возвращает ли путь JSON какой-либо элемент для указанного значения JSON? (Это применимо только к выражениям JSON path в стандарте SQL, но не к выражениям проверки предикатов, так как последние всегда возвращают значение.)
|
Функция возвращает результат проверки предиката JSON path для
указанного значения JSON.
(Это применимо только к
с выражениям
проверки предикатов, а не к выражениям JSON path в стандарте SQL,
поскольку результат будет возвращен только в том случае,
|
Данный jsonpath операторы @?
и @@ подавляют следующие ошибки: отсутствие поля объекта или элемента массива, неверный тип элемента JSON, а также ошибки при обработке дат и чисел. jsonpathВ связанных функциях, описанных ниже, также можно настроить подавление ошибок данных типов. Данное поведение может быть полезным при поиске в коллекциях JSON-документов с различной структурой.
Таблица 2.6.47 содержит описание функций, доступных для формирования json и jsonb значений.
Для некоторых функций в данной таблице предусмотрено RETURNING предложение,
определяющее тип возвращаемых данных. В качестве такого типа должен быть указан тип json,
jsonb, bytea, строковый символьный тип (text,
char, или varchar) либо тип,
поддерживающий приведение к типу json.
По умолчанию возвращается значение типа json type is returned.
Таблица 2.6.47. Функции создания JSON
Функция Описание Примеры |
|---|
|
Преобразует любое значение языка SQL в значение типа
|
Данная функция преобразует массив языка SQL в массив JSON. Поведение функции идентично,
функции
|
Данная функция формирует массив JSON либо из набора
|
Преобразует составное значение языка SQL в объект JSON. Такое поведение
аналогично выражению
|
Формирует JSON-массив, потенциально содержащий данные различных типов, из вариативного
списка аргументов. Каждый аргумент преобразуется согласно
правилам функции
|
Формирует JSON-объект из вариативного списка аргументов. Согласно соглашению,
список аргументов состоит из чередующихся ключей и значений. Аргументы,
являющиеся ключами, приводятся к типу text; аргументы, являющиеся значениями, преобразуются согласно
правилам функции
|
Формирует объект JSON из всех заданных пар «ключ-значение»
или пустой объект, если пары не указаны.
|
|
Данная функция формирует объект JSON из текстового массива. Массив должен иметь либо ровно одну размерность с четным числом элементов, в этом случае они интерпретируются как чередующиеся пары «ключ-значение», либо две размерности такие, что каждый внутренний массив содержит ровно два элемента, которые интерпретируются как пара «ключ-значение». Все значения преобразуются в строковые значения JSON.
|
Данная форма
|
|
Преобразует заданное выражение, представленное как
|
|
Функция преобразует заданное скалярное значение языка SQL в скалярное значение JSON. Если входное значение имеет значение NULL, то SQL возвращается значение null. Если входное значение представляет собой число или логическое значение, то соответствующее число или логическое значение JSON возвращается. Для любого другого типа данных возвращается строка JSON.
|
|
Данная функция преобразует выражение языка SQL/JSON в символьную или двоичную строку.
|
Таблица 2.6.48 подробно описывает средства языка SQL/JSON для тестирования данных JSON.
Таблица 2.6.48. Функции проверки SQL/JSON
Таблица 2.6.49 представлены функции, доступные для обработки json и jsonb значений.
Таблица 2.6.49. Функции для обработки данных JSON
Функция Описание Примеры |
|---|
Функция разворачивает JSON-массив верхнего уровня в набор JSON-значений.
value ----------- 1 true [2,false]
|
Функция разворачивает JSON-массив верхнего уровня в набор
value ----------- foo bar
|
Функция возвращает количество элементов в JSON-массиве верхнего уровня.
|
Данная функция разворачивает JSON-объект верхнего уровня в набор пар «ключ/значение».
key | value -----+------- a | "foo" b | "bar"
|
Данная функция разворачивает JSON-объект верхнего уровня в набор пар «ключ/значение».
Возвращаемые
key | value -----+------- a | foo b | bar
|
Функция извлекает вложенный JSON-объект по указанному пути.
(Данная операция функционально эквивалентна
|
Данный оператор извлекает вложенный объект JSON по указанному пути как
|
Функция возвращает набор ключей объекта JSON верхнего уровня.
json_object_keys ------------------ f1 f2
|
Функция разворачивает объект JSON верхнего уровня в строку, имеющую составной тип
из Для преобразования значения JSON в тип языка SQL выходного столбца последовательно применяются следующие правила:
Хотя в приведенном ниже примере используется константное значение JSON, в типичных сценариях использования
предполагается ссылка на
a | b | c
---+-----------+-------------
1 | {2,"a b"} | (4,"a b c")
|
Функция для тестирования
jsonb_populate_record_valid ----------------------------- f (1 строка)
ERROR: value too long for type character(2)
jsonb_populate_record_valid ----------------------------- t (1 row)
a ---- aa (1 row)
|
Функция разворачивает массив объектов JSON верхнего уровня в набор строк, имеющих
составной тип данных
a | b ---+--- 1 | 2 3 | 4
|
Функция разворачивает объект JSON верхнего уровня в строку, имеющую составной тип
определяемый с помощью
a | b | c | d | r
---+---------+---------+---+---------------
1 | [1,2,3] | {1,2,3} | | (123,"a b c")
|
Функция разворачивает массив объектов JSON верхнего уровня в набор строк, имеющих
составной тип, определяемый
a | b ---+----- 1 | foo 2 |
|
Возвращает значение
|
Если
|
Возвращает значение
|
Рекурсивно удаляет из заданного JSON-значения все поля объектов, имеющие значение null. Значения null, не являющиеся полями объектов, остаются без изменений.
|
Проверяет, возвращает ли путь JSON какие-либо элементы для указанного значения JSON.
значение.
(Это применимо только к выражениям JSON path в стандарте SQL, но не к
выражениям проверки
предикатов, так как последние всегда возвращают значение.)
Если указан
|
Возвращает логический результат языка SQL при проверке предиката пути JSON
для указанного значения JSON.
(Это применимо только к
с выражениям
проверки предикатов, а не к выражениям JSON path в стандарте SQL,
так как это приведет либо к ошибке, либо к возврату
|
Функция возвращает все элементы JSON, полученные в результате применения пути JSON к указанному
значению JSON.
Для выражений пути JSON стандарта языка SQL функция возвращает значения JSON,
выбранные из
jsonb_path_query ------------------ 2 3 4
|
Функция возвращает все элементы JSON, полученные в результате применения пути JSON к указанному
значение JSON, представленное в виде массива JSON.
Данные параметры идентичны параметрам функции
в
|
Функция возвращает первый элемент JSON, полученный в результате выполнения пути JSON для
заданного значения JSON, или значение `NULL`,
|
Данные функции работают аналогично функциям-аналогам, описанным выше без
с
|
|
Преобразует заданное значение JSON в текст с отступами для удобства чтения.
[
{
"f1": 1,
"f2": null
},
2
]
|
|
Возвращает тип значения JSON верхнего уровня в виде текстовой строки.
Допустимые типы:
|
Выражения путей SQL/JSON определяют элементы, извлекаемые из значений JSON, аналогично выражениям XPath, используемым для доступа к содержимому документов XML. В Digital Q.DataBase,
выражения путей реализованы как тип данных jsonpath
и могут использовать любые элементы, описанные в
Раздел 2.5.14.7.
Функции и операторы запросов JSON
передают предоставленное выражение пути в механизм обработки путей
для вычисления. Если выражение соответствует запрашиваемым данным JSON,
возвращается соответствующий элемент JSON или набор элементов.
Если совпадение не найдено, результатом будет NULL,
false, или ошибка, в зависимости от конкретной функции.
Выражения путей пишутся на языке путей SQL/JSON
и могут включать в себя арифметические выражения и функции.
Выражение пути состоит из последовательности элементов, допустимых для
типа данных jsonpath .
Выражение пути обычно вычисляется слева направо, однако
для изменения порядка операций можно использовать скобки.
При успешном завершении вычисления формируется последовательность элементов JSON,
и результат возвращается в функцию запроса JSON,
которая завершает заданную операцию.
Для обращения к запрашиваемому значению JSON (так называемый
элемент контекста), используйте $ переменную
в выражении пути. Первым элементом пути всегда должен быть $. За ним могут следовать один или несколько
операторов доступа,
которые выполняют переход по структуре JSON уровень за уровнем для извлечения подэлементов
элемента контекста. Каждый оператор доступа обрабатывает результаты предыдущего этапа вычисления, формируя ноль, один или несколько выходных элементов на основе каждого входного элемента.
Например, предположим, что имеются данные JSON от GPS-трекера, которые необходимо проанализировать, такие как:
SELECT '{
"track": {
"segments": [
{
"location": [ 47.763, 13.4034 ],
"start time": "2018-10-14 10:05:14",
"HR": 73
},
{
"location": [ 47.706, 13.2635 ],
"start time": "2018-10-14 10:39:21",
"HR": 135
}
]
}
}' AS json \gset
(Приведенный выше пример можно скопировать и вставить
в psql для подготовки данных к последующим
примерам. После этого команда psql будет выполнено развертывание :'json' в строковую константу с корректным использованием кавычек, содержащую значение JSON.)
Для получения доступных сегментов трека необходимо использовать
. оператор доступа для перехода по вложенным объектам JSON, например:
ключ
=>select jsonb_path_query(:'json', '$.track.segments');jsonb_path_query ----------------------------------------------------------- ----------------------------------------------------------- --------------------------------------------- [{"HR": 73, "location": [47.763, 13.4034], "start time": "2018-10-14 10:05:14"}, {"HR": 135, "location": [47.706, 13.2635], "start time": "2018-10-14 10:39:21"}]
Для получения содержимого массива обычно используется
[*] оператор.
Следующий пример возвращает координаты местоположения для всех
доступных сегментов трека:
=>select jsonb_path_query(:'json', '$.track.segments[*].location');jsonb_path_query ------------------- [47.763, 13.4034] [47.706, 13.2635]
В данном случае обработка начинается со всего входного значения JSON ($),
затем .track аксессор выбирает объект JSON, связанный с ключом "track" ключ объекта, после чего .segments аксессор выбирает массив JSON, соответствующий ключу "segments" внутри этого
объекта, далее [*] оператор доступа выбрал каждый элемент данного массива (формируя последовательность элементов), а затем .location аксессор выбирает массив JSON, соответствующий ключу "location" ключ внутри каждого из
этих объектов. В данном примере каждый из этих объектов содержал
ключ "location" key; но если какой-либо из них не содержал данных,
то .location оператор доступа просто не сформировал бы результат для данного входного элемента.
Для получения координат только первого сегмента можно
указать соответствующий индекс в []
операторе доступа. Следует помнить, что индексация в массивах JSON начинается с нуля:
=>select jsonb_path_query(:'json', '$.track.segments[0].location');jsonb_path_query ------------------- [47.763, 13.4034]
Результат каждого шага вычисления пути может быть обработан одним или несколькими jsonpath операторами и методами,
перечисленными в Раздел 2.6.16.2.3.
Перед именем каждого метода должна стоять точка. Например,
размер массива можно получить следующим образом:
=>select jsonb_path_query(:'json', '$.track.segments.size()');jsonb_path_query ------------------ 2
Дополнительные примеры использования jsonpath операторов
и методов в выражениях путей приведены далее в
Раздел 2.6.16.2.3.
Путь также может содержать
фильтрующие выражения, которые функционируют аналогично оператору
WHERE предложение в языке SQL. Выражение фильтра начинается со
знака вопроса и содержит условие, указанное в скобках:
? (условие)
Выражения фильтра должны указываться непосредственно после того этапа вычисления пути, к которому они применяются. Результат этого этапа фильтруется для включения только тех элементов, которые удовлетворяют заданному условию. Стандарт SQL/JSON определяет трехзначную логику, поэтому условие может принимать значения true, false,
или unknown. The unknown значение
играет ту же роль, что и в языке SQL NULL и может быть проверено
с помощью is unknown предиката. На последующих этапах вычисления пути используются только те элементы, для которых выражение фильтра вернуло значение true.
Функции и операторы, которые могут применяться в выражениях фильтра, перечислены в Таблица 2.6.51. Внутри
выражения фильтра переменная @ обозначает текущее обрабатываемое значение (то есть один из результатов предшествующего этапа пути). Операторы доступа могут быть
указаны после переменной @ для извлечения составных
частей элементов.
Предположим, например, что требуется получить все значения частоты пульса, превышающие 130. Сделать это можно следующим образом:
=>select jsonb_path_query(:'json', '$.track.segments[*].HR ? (@ > 130)');jsonb_path_query ------------------ 135
Чтобы получить время начала сегментов с такими значениями, необходимо отсеять нерелевантные сегменты перед выбором времени начала. В этом случае выражение фильтра применяется на предыдущем шаге, и путь, используемый в условии, изменяется:
=>select jsonb_path_query(:'json', '$.track.segments[*] ? (@.HR > 130)."start time"');jsonb_path_query ----------------------- "2018-10-14 10:39:21"
При необходимости можно последовательно использовать несколько выражений фильтрации. В следующем примере выбирается время начала всех сегментов, содержащих точки с соответствующими координатами и высокими показателями частоты пульса:
=>select jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4) ? (@.HR > 130)."start time"');jsonb_path_query ----------------------- "2018-10-14 10:39:21"
Допускается также использование выражений фильтрации на различных уровнях вложенности. В следующем примере сначала производится фильтрация всех сегментов по местоположению, после чего для данных сегментов возвращаются высокие значения частоты сердечных сокращений (при их наличии):
=>select jsonb_path_query(:'json', '$.track.segments[*] ? (@.location[1] < 13.4).HR ? (@ > 130)');jsonb_path_query ------------------ 135
Выражения фильтрации также могут быть вложены друг в друга. В данном примере возвращается размер трека, если он содержит сегменты с высокими значениями частоты сердечных сокращений; в противном случае возвращается пустая последовательность:
=>select jsonb_path_query(:'json', '$.track ? (exists(@.segments[*] ? (@.HR > 130))).segments.size()');jsonb_path_query ------------------ 2
Digital Q.DataBaseРеализация языка путей SQL/JSON имеет следующие отклонения от стандарта SQL/JSON.
В качестве расширения стандарта SQL Digital Q.DataBase путь может представлять собой логический предикат, тогда как стандарт SQL допускает использование предикатов только внутри фильтров. В то время как списочные выражения в стандарте SQL возвращают соответствующие элементы запрашиваемого значения JSON, выражения проверки предикатов возвращают единственное трехзначное значение — jsonb результат
вычисления предиката: true,
false, или null.
Например, можно составить следующее выражение фильтра согласно стандарту SQL:
=>select jsonb_path_query(:'json', '$.track.segments ?(@[*].HR > 130)');jsonb_path_query ----------------------------------------------------------- ---------------------- {"HR": 135, "location": [47.706, 13.2635], "start time": "2018-10-14 10:39:21"}
Аналогичное выражение проверки предиката просто возвращает значение true, указывающее на наличие совпадения:
=>select jsonb_path_query(:'json', '$.track.segments[*].HR > 130');jsonb_path_query ------------------ true
Выражения проверки предикатов являются обязательными для использования в
@@ операторе (а также в
jsonb_path_match функции), и их не следует применять
с помощью @? оператора (или
jsonb_path_exists функции).
Существуют незначительные различия в интерпретации шаблонов регулярных выражений, используемых в like_regex фильтрах, как
описано в Раздел 2.6.16.2.4.
При выполнении запросов к данным JSON выражение пути может не соответствовать фактической структуре данных JSON. Попытка обращения к несуществующему члену объекта или элементу массива определяется как структурная ошибка. Выражения пути языка SQL/JSON имеют два режима обработки структурных ошибок:
lax (по умолчанию) — механизм обработки путей неявно адаптирует запрашиваемые данные к указанному пути. Любые структурные ошибки, которые не могут быть исправлены описанным ниже способом, подавляются, не возвращая совпадений.
strict — при возникновении структурной ошибки выдается ошибка.
Режим lax упрощает сопоставление JSON-документа и выражения пути, когда данные JSON не соответствуют ожидаемой схеме. Если операнд не соответствует требованиям определенной операции, он может быть автоматически упакован в массив языка SQL/JSON или распакован путем преобразования его элементов в последовательность языка SQL/JSON перед выполнением операции. Кроме того, в режиме lax операторы сравнения автоматически разворачивают свои операнды, что позволяет сравнивать массивы языка SQL/JSON без дополнительной обработки. Массив размером 1 считается равным его единственному элементу. Автоматическое разворачивание не выполняется, если:
Выражение пути содержит type() или
size() методы, возвращающие тип
и количество элементов в массиве соответственно.
Запрашиваемые данные JSON содержат вложенные массивы. В этом случае разворачивается только самый внешний массив, тогда как все внутренние массивы остаются без изменений. Таким образом, неявное разворачивание может выполняться только на один уровень вглубь на каждом шаге вычисления пути.
Например, при обработке запроса к перечисленным выше данным GPS в режиме lax можно абстрагироваться от того факта, что в них хранится массив сегментов:
=>select jsonb_path_query(:'json', 'lax $.track.segments.location');jsonb_path_query ------------------- [47.763, 13.4034] [47.706, 13.2635]
В режиме strict указанный путь должен точно соответствовать структуре запрашиваемого документа JSON, поэтому использование данного выражения пути приведет к ошибке:
=>select jsonb_path_query(:'json', 'strict $.track.segments.location');ERROR: jsonpath member accessor can only be applied to an object
Для получения того же результата, что и в режиме lax, необходимо явно выполнить развертывание
segments массива:
=>select jsonb_path_query(:'json', 'strict $.track.segments[*].location');jsonb_path_query ------------------- [47.763, 13.4034] [47.706, 13.2635]
Поведение режима lax при развертывании может привести к получению неожиданных результатов. Например, представленный ниже запрос, использующий .** аксессор,
выбирает каждое значение HR дважды:
=>select jsonb_path_query(:'json', 'lax $.**.HR');jsonb_path_query ------------------ 73 135 73 135
Это происходит вследствие того, что .** аксессор выбирает как
сам segments массив и каждый из его элементов, тогда как .HR аксессор автоматически развертывает массивы при использовании режима lax. Во избежание непредвиденных результатов рекомендуется использовать функцию .** аксессор доступен только в строгом режиме (strict mode). Следующий
запрос выбирает каждое HR значение только один раз:
=>select jsonb_path_query(:'json', 'strict $.**.HR');jsonb_path_query ------------------ 73 135
Распаковка массивов также может привести к неожиданным результатам. Рассмотрим данный
пример, в котором выбираются все массивы location:
=>select jsonb_path_query(:'json', 'lax $.track.segments[*].location');jsonb_path_query ------------------- [47.763, 13.4034] [47.706, 13.2635] (2 rows)
Как и ожидалось, функция возвращает массивы целиком. Однако применение выражения фильтрации приводит к распаковке массивов для вычисления каждого элемента; при этом возвращаются только те элементы, которые соответствуют данному выражению:
=>select jsonb_path_query(:'json', 'lax $.track.segments[*].location ?(@[*] > 15)');jsonb_path_query ------------------ 47.763 47.706 (2 rows)
Это происходит вопреки тому, что выражение пути выбирает массивы целиком. Для восстановления выборки массивов используйте строгий режим (strict mode):
=>select jsonb_path_query(:'json', 'strict $.track.segments[*].location ?(@[*] > 15)');jsonb_path_query ------------------- [47.763, 13.4034] [47.706, 13.2635] (2 rows)
Таблица 2.6.50 содержит описание операторов и
методов, доступных в jsonpath. Обратите внимание: в то время как унарные операторы и методы могут применяться к нескольким значениям, полученным на предыдущем шаге пути, бинарные операторы (сложение и т. д.) могут применяться только к одиночным значениям. В нестрогом режиме (lax mode) методы, применяемые к массиву, будут выполнены для каждого элемента в этом массиве. Исключение составляют методы
.type() и .size(), которые применяются непосредственно к самому массиву.
Таблица 2.6.50. jsonpath Операторы и методы
Оператор/метод Описание Примеры |
|---|
Сложение
|
Унарный плюс (операция отсутствует); в отличие от сложения, данный оператор может выполнять итерацию по множественным значениям
|
Вычитание
|
Отрицание; в отличие от вычитания, данная операция может применяться итеративно к множественным значениям
|
Умножение
|
Деление
|
Остаток от деления (modulo)
|
Тип элемента JSON (см.
|
Размер элемента JSON (количество элементов массива или 1, если элемент не является массивом)
|
Логическое значение, полученное путем преобразования из типа boolean, числа или строки JSON
|
Строковое значение, полученное путем преобразования из JSON-типов boolean, number, string или datetime
|
Число с плавающей точкой, полученное путем преобразования из JSON-типов number или string
|
Ближайшее целое число, большее или равное заданному
|
Ближайшее целое число, меньшее или равное заданному
|
Абсолютное значение заданного числа
|
Значение типа bigint, полученное путем преобразования числа или строки JSON
|
Округленное десятичное значение, полученное путем преобразования числа или строки JSON
(
|
Целочисленное значение, полученное путем преобразования числа или строки JSON
|
Числовое значение, полученное путем преобразования числа или строки JSON
|
Значение даты и времени, преобразованное из строки
|
Значение даты и времени, преобразованное из строки с использованием
указанного
|
Значение даты, преобразованное из строки
|
Значение времени без часового пояса, преобразованное из строки
|
Значение времени без часового пояса, преобразованное из строки, с дробной частью секунды, приведенные к заданной точности
|
Значение времени с часовым поясом, преобразованное из строки
|
Значение времени с часовым поясом, преобразованное из строки, с дробной частью секунд секунды, приведенные к заданной точности
|
Значение метки времени без часового пояса, преобразованное из строки
|
Значение метки времени без часового пояса, преобразованное из строки, с дробной частью секунд, приведенной к заданной точности
|
Значение типа timestamp with time zone, преобразованное из строкового представления
|
Значение типа timestamp with time zone, преобразованное из строкового представления, с дробной частью секунды, приведенные к заданной точности
|
Пары «ключ-значение» объекта, представленные в виде массива объектов,
содержащего три поля:
|
Тип результата методов datetime() и
datetime(
может быть шаблон)date, timetz, time,
timestamptz, или timestamp.
Оба метода определяют тип возвращаемого значения динамически.
Метод datetime() последовательно сопоставляет входную строку с форматами ISO для типов date, timetz, time,
timestamptz, и timestamp. Работа прекращается на первом подходящем формате, и возвращается соответствующий тип данных.
Метод datetime(
определяет тип результата в соответствии с полями, указанными в предоставленной строке шаблона.
шаблон)
Метод datetime() и
datetime( методы
используют те же правила синтаксического анализа, что и шаблон)to_timestamp функция языка SQL
(см. Раздел 2.6.8), за тремя
исключениями. Во-первых, данные методы не допускают использования несоответствующих шаблонов
шаблона. Во-вторых, в строке шаблона разрешены только следующие разделители:
знак минуса, точка, косая черта (слеш), запятая, апостроф,
точка с запятой, двоеточие и пробел. В-третьих, разделители в строке шаблона
должны строго соответствовать входной строке.
Если требуется сравнение различных типов даты и времени, применяется неявное приведение типов. date значение может быть приведено к типу timestamp
OR timestamptz, timestamp может быть приведен к типу
timestamptz, и time до timetz.
Однако все эти преобразования, за исключением первого, зависят от текущей
TimeZone настройки и, следовательно, могут выполняться только
в рамках функций, учитывающих jsonpath часовой пояс. Аналогичным образом, прочие связанные с датой и временем методы, преобразующие строки в типы даты/времени, также осуществляют данное приведение типов, которое может задействовать текущую
TimeZone настройки. Следовательно, данные преобразования также могут быть выполнены только внутри функций, учитывающих jsonpath
часовой пояс.
Таблица 2.6.51 содержит доступные элементы выражений фильтрации.
Таблица 2.6.51. jsonpath Элементы выражений фильтрации
Предикат/Значение Описание Примеры |
|---|
Сравнение на равенство (данный оператор, как и другие операторы сравнения, применим ко всем скалярным значениям JSON)
|
Сравнение на неравенство
|
Операция сравнения «меньше»
|
Операция сравнения «меньше или равно»
|
Операция сравнения «больше»
|
Операция сравнения «больше или равно»
|
Константа JSON
|
Константа JSON
|
Константа JSON
|
Логический оператор AND
|
Логический оператор OR
|
Логический оператор NOT
|
Проверяет, является ли логическое условие
|
Данный оператор проверяет, соответствует ли первый операнд регулярному выражению,
заданному во втором операнде, с возможными модификаторами,
описанными в строке
|
Данный оператор проверяет, является ли второй операнд начальной подстрокой первого операнда.
|
Данная функция проверяет, соответствует ли выражение пути хотя бы одному элементу SQL/JSON.
Возвращает значение
|
Выражения пути SQL/JSON позволяют выполнять сопоставление текста с регулярным выражением при помощи оператора like_regex фильтра. Например, приведенный ниже запрос пути SQL/JSON найдет без учета регистра все строки в массиве, начинающиеся с английской гласной:
$[*] ? (@ like_regex "^[aeiou]" flag "i")
Необязательное флаг строка может содержать один или несколько символов
i для поиска без учета регистра букв,
m разрешить ^
и $ для сопоставления с символами новой строки,
s разрешить . для сопоставления с символом новой строки,
и q для экранирования всего шаблона (что сводит операцию к простому поиску подстроки).
Стандарт SQL/JSON заимствует определение регулярных выражений из LIKE_REGEX оператора, который, в свою очередь, использует стандарт XQuery. Digital Q.DataBase в настоящее время не поддерживает
LIKE_REGEX оператор. Следовательно,
фильтр like_regex реализован с использованием механизма регулярных выражений стандарта POSIX, описанного в
Раздел 2.6.7.3. Это приводит к различным незначительным расхождениям со стандартным поведением языка SQL/JSON, которые перечислены в
Раздел 2.6.7.3.8. Однако следует учитывать, что описанные там несовместимости буквенных флагов не распространяются на язык SQL/JSON, так как в нем выполняется трансляция буквенных флагов XQuery для обеспечения соответствия ожиданиям механизма стандарта POSIX.
Необходимо учитывать, что аргумент-шаблон функции like_regex
является строковым литералом пути JSON, составленным согласно правилам, изложенным в
Раздел 2.5.14.7. В частности, это означает, что любые символы обратной косой черты, используемые в регулярном выражении, должны быть удвоены. Например, для поиска соответствия строковым значениям корневого документа, содержащим только цифры:
$.* ? (@ like_regex "^\\d+$")
Функции SQL/JSON JSON_EXISTS(),
JSON_QUERY(), и JSON_VALUE()
описано в Таблица 2.6.52 могут быть использованы
для выполнения запросов к документам JSON. Каждая из этих функций применяет
path_expression (запрос на языке SQL/JSON path) к
context_item (документу). См.
Раздел 2.6.16.2 для получения подробной информации о том, что
может содержать path_expression . Выражение
path_expression также может ссылаться на переменные,
значения которых указываются под соответствующими именами в
PASSING предложении, поддерживаемом каждой функцией.
context_item может быть jsonb значением
или символьной строкой, которая может быть успешно приведена к типу jsonb.
Таблица 2.6.52. Функции запросов SQL/JSON
Сигнатура функции Описание Пример(ы) |
|---|
Примеры:
ОШИБКА: индекс массива jsonpath вышел за границы диапазона
|
Примеры:
ERROR: malformed array literal: "[1, 2]" DETAIL: Missing "]" after array dimensions.
|
Примеры:
|
Данный context_item выражение преобразуется в тип
jsonb посредством неявного приведения, если оно еще не относится к типу jsonb. Следует, однако, учитывать, что любые ошибки синтаксического анализа, возникающие при таком преобразовании, генерируются безусловно, то есть не обрабатываются в соответствии с заданным или подразумеваемым ON ERROR
предложение.
JSON_VALUE() возвращает значение NULL языка SQL, если
path_expression возвращает данные JSON
null, тогда как JSON_QUERY() возвращает
данные JSON null в исходном виде.
JSON_TABLE представляет собой функцию стандарта SQL/JSON, которая
выполняет запросы к JSON данным
и представляет результаты в виде реляционного представления, доступного как
обычная таблица языка SQL. Можно использовать JSON_TABLE внутри
предложения FROM в SELECT,
UPDATE, или DELETE а также в качестве источника данных
в инструкции MERGE statement.
Принимая на вход данные JSON, JSON_TABLE использует выражение JSON path для извлечения части предоставленных данных, которая будет использоваться в качестве
шаблона строки для сформированного представления. Каждое значение SQL/JSON, заданное шаблоном строки, служит источником данных для отдельной строки в сформированном представлении.
Для разделения шаблона строки на столбцы JSON_TABLE
предоставляет COLUMNS предложение, определяющее схему создаваемого представления. Для каждого столбца может быть указано отдельное выражение пути JSON; оно вычисляется применительно к шаблону строки для получения значения SQL/JSON, которое становится значением соответствующего столбца в данной выходной строке.
Данные JSON, хранящиеся на вложенном уровне шаблона строки, могут быть извлечены с помощью
предложения NESTED PATH предложение. Каждое такое
NESTED PATH предложение может быть использовано для формирования одного или нескольких столбцов на основе данных с вложенного уровня шаблона строки. Данные
столбцы могут быть определены с помощью предложения COLUMNS структура которого
аналогична предложению COLUMNS верхнего уровня. Строки, сформированные из
NESTED COLUMNS, называются дочерние строки и соединяются
со строкой, сформированной на основе столбцов, указанных в родительском элементе,
COLUMNS предложение для получения строки в результирующем представлении. Сами дочерние
столбцы могут содержать NESTED PATH
спецификацию, позволяющую извлекать данные, находящиеся на произвольных уровнях вложенности. Столбцы, сформированные несколькими NESTED PATHна одном и том же уровне, рассматриваются как одноуровневые элементы по отношению друг к
другу, и их строки после соединения с родительской строкой объединяются с помощью
оператора UNION.
Строки, сформированные функцией JSON_TABLE присоединяются к сгенерировавшей их строке посредством латерального соединения (LATERAL JOIN), что исключает необходимость явного соединения сконструированного представления с исходной таблицей, содержащей JSON
данные.
Синтаксис:
JSON_TABLE (
context_item, path_expression [ AS json_path_name ] [ PASSING { value AS varname } [, ...] ]
COLUMNS ( json_table_column [, ...] )
[ { ERROR | EMPTY [ARRAY]} ON ERROR ]
)
где json_table_column следующее:
name FOR ORDINALITY
| name тип
[ FORMAT JSON [ENCODING UTF8]]
[ PATH path_expression ]
[ { WITHOUT | WITH { CONDITIONAL | [UNCONDITIONAL] } } [ ARRAY ] WRAPPER ]
[ { KEEP | OMIT } QUOTES [ ON SCALAR STRING ] ]
[ { ERROR | NULL | EMPTY { [ARRAY] | OBJECT } | DEFAULT выражение } ON EMPTY ]
[ { ERROR | NULL | EMPTY { [ARRAY] | OBJECT } | DEFAULT выражение } ON ERROR ]
| name тип EXISTS [ PATH path_expression ]
[ { ERROR | TRUE | FALSE | UNKNOWN } ON ERROR ]
| NESTED [ PATH ] path_expression [ AS json_path_name ] COLUMNS ( json_table_column [, ...] )
Ниже каждый элемент синтаксиса описан более подробно.
context_item, path_expression [ AS json_path_name ] [ PASSING { value AS varname } [, ...]]
context_item определяет входной документ
для выполнения запроса, path_expression является выражением пути
на языке SQL/JSON, определяющим запрос, а json_path_name
является необязательным именем для path_expression.
Необязательное PASSING предложение предоставляет значения данных для
переменных, указанных в path_expression.
Результат вычисления входных данных с применением вышеупомянутых элементов
называется шаблона строки, который используется в качестве источника значений строк в формируемом представлении.
COLUMNS ( json_table_column [, ...] )
COLUMNS предложение, определяющее схему формируемого представления. В данном предложении можно указать каждый столбец, который будет заполнен значением на языке SQL/JSON, полученным в результате применения выражения пути JSON к шаблону строки. json_table_column имеет
следующие варианты:
name FOR ORDINALITY
Добавляет столбец порядковых номеров, обеспечивающий последовательную нумерацию строк, начиная с 1. Для каждого NESTED PATH (см. ниже) используется собственный счетчик для любых вложенных столбцов порядковых номеров.
name тип
[FORMAT JSON [ENCODING UTF8]]
[ PATH path_expression ]
Вставляет значение на языке SQL/JSON, полученное в результате применения
path_expression сопоставленный с шаблоном строки в выходную строку представления после его приведения к указанному
тип.
Указание данного параметра FORMAT JSON явно указывает на то, что значение должно быть корректным json объектом. Указание данного параметра имеет смысл только FORMAT JSON если
тип является одним из bpchar,
bytea, character varying, name,
json, jsonb, text, или домен, основанный на этих типах данных.
Дополнительно можно указать WRAPPER и
QUOTES предложения (clauses) для форматирования выходных данных. Обратите внимание, что указание OMIT QUOTES переопределяет действие параметра
FORMAT JSON если он также указан, поскольку литералы без кавычек не являются корректными json значений.
При необходимости можно использовать ON EMPTY и
ON ERROR предложения для определения того, следует ли генерировать ошибку
или возвращать указанное значение в случаях, когда результат вычисления пути JSON
пуст, когда возникает ошибка при вычислении пути JSON или когда
выполняется приведение значения языка SQL/JSON к указанному типу соответственно. По умолчанию в обоих случаях возвращается NULL value.
Данное предложение внутренне преобразуется и имеет ту же семантику, что и
JSON_VALUE или JSON_QUERY.
Последний вариант используется, если указанный тип не является скалярным или если любой из
FORMAT JSON, WRAPPER, или
QUOTES присутствует предложение.
name тип
EXISTS [ PATH path_expression ]
Вставляет логическое значение, полученное в результате применения
path_expression к шаблону строки,
в выходную строку представления после его приведения к указанному
тип.
Данное значение указывает на то, возвращает ли применение PATH
выражения к шаблону строки какие-либо значения.
Указанный тип должен поддерживать приведение из
boolean типа.
При необходимости можно использовать ON ERROR для указания того, следует ли генерировать ошибку или возвращать указанное значение при возникновении ошибки в ходе вычисления пути JSON или при приведении значения SQL/JSON к указанному типу. По умолчанию возвращается логическое значение
FALSE.
Данное предложение внутренне преобразуется и имеет ту же семантику, что и
JSON_EXISTS.
NESTED [ PATH ] path_expression [ AS json_path_name ]
COLUMNS ( json_table_column [, ...] )
Извлекает значения SQL/JSON из вложенных уровней шаблона строки,
формирует один или несколько столбцов, определенных в COLUMNS
подпредложении, и вставляет извлеченные значения SQL/JSON в эти
столбцы. Предложение json_table_column
выражение в COLUMNS подпредложение использует тот же синтаксис, что и в родительском предложении COLUMNS предложении.
NESTED PATH синтаксис является рекурсивным,
что позволяет переходить на несколько уровней вложенности путём указания нескольких
NESTED PATH вложенные друг в друга подвыражения.
Это позволяет раскрыть иерархию объектов и массивов JSON
за один вызов функции вместо последовательного объединения нескольких вызовов
JSON_TABLE выражения в операторе языка SQL.
В каждом из вариантов json_table_column описанных
выше, если PATH предложение опущено, применяется выражение пути
$. , в котором
namename является указанным именем столбца.
AS json_path_name
Необязательное json_path_name служит идентификатором предоставленного path_expression.
Данное имя должно быть уникальным и отличаться от имен столбцов.
ERROR | EMPTY } ON ERROR
Необязательное ON ERROR может использоваться для указания способа обработки ошибок при вычислении выражения верхнего уровня
path_expression. Используйте ERROR
если требуется генерация исключения при ошибке, и EMPTY для возврата пустой таблицы, то есть таблицы, содержащей 0 строк. Обратите внимание на то, что данное предложение не влияет на ошибки, возникающие при вычислении значений в столбцах; поведение в таких случаях зависит от того,
ON ERROR Данное предложение указывается для конкретного столбца.
Примеры
В нижеследующих примерах используется таблица, содержащая данные типа JSON:
CREATE TABLE my_films ( js jsonb );
INSERT INTO my_films VALUES (
'{ "favorites" : [
{ "kind" : "comedy", "films" : [
{ "title" : "Bananas",
"director" : "Woody Allen"},
{ "title" : "The Dinner Game",
"director" : "Francis Veber" } ] },
{ "kind" : "horror", "films" : [
{ "title" : "Psycho",
"director" : "Alfred Hitchcock" } ] },
{ "kind" : "thriller", "films" : [
{ "title" : "Vertigo",
"director" : "Alfred Hitchcock" } ] },
{ "kind" : "drama", "films" : [
{ "title" : "Yojimbo",
"director" : "Akira Kurosawa" } ] }
] }');
В следующем запросе показано использование функции JSON_TABLE для
преобразования объектов JSON из my_films таблицы
в представление со столбцами, соответствующими ключам kind,
title, и директоров содержащимся в
исходном объекте JSON, а также со столбцом порядковых номеров:
SELECT jt.* FROM my_films, JSON_TABLE (js, '$.favorites[*]' COLUMNS ( id FOR ORDINALITY, kind text PATH '$.kind', title text PATH '$.films[*].title' WITH WRAPPER, director text PATH '$.films[*].director' WITH WRAPPER)) AS jt;
id | kind | title | director ----+----------+--------------------------------+---------------------------------- 1 | comedy | ["Bananas", "The Dinner Game"] | ["Woody Allen", "Francis Veber"] 2 | horror | ["Psycho"] | ["Alfred Hitchcock"] 3 | thriller | ["Vertigo"] | ["Alfred Hitchcock"] 4 | drama | ["Yojimbo"] | ["Akira Kurosawa"] (4 строки)
Ниже приведена модифицированная версия вышеуказанного запроса, демонстрирующая использование PASSING аргументы в фильтре выражения пути JSON верхнего уровня, а также от различных параметров для отдельных столбцов:
SELECT jt.* FROM
my_films,
JSON_TABLE (js, '$.favorites[*] ? (@.films[*].director == $filter)'
PASSING 'Alfred Hitchcock' AS filter, 'Vertigo' AS filter2
COLUMNS (
id FOR ORDINALITY,
kind text PATH '$.kind',
title text FORMAT JSON PATH '$.films[*].title' OMIT QUOTES,
director text PATH '$.films[*].director' KEEP QUOTES)) AS jt;
id | kind | title | director ----+----------+---------+-------------------- 1 | horror | Psycho | "Alfred Hitchcock" 2 | thriller | Vertigo | "Alfred Hitchcock" (2 строки)
Ниже приведена модифицированная версия вышеуказанного запроса, демонстрирующая использование NESTED PATH для заполнения столбцов title и director, которая иллюстрирует способ их объединения с родительскими столбцами id и kind:
SELECT jt.* FROM
my_films,
JSON_TABLE ( js, '$.favorites[*] ? (@.films[*].director == $filter)'
PASSING 'Alfred Hitchcock' AS filter
COLUMNS (
id FOR ORDINALITY,
kind text PATH '$.kind',
NESTED PATH '$.films[*]' COLUMNS (
title text FORMAT JSON PATH '$.title' OMIT QUOTES,
director text PATH '$.director' KEEP QUOTES))) AS jt;
id | kind | title | director ----+----------+---------+-------------------- 1 | horror | Psycho | "Alfred Hitchcock" 2 | thriller | Vertigo | "Alfred Hitchcock" (2 строки)
Ниже приведен тот же запрос, но без применения фильтра в корневом пути:
SELECT jt.* FROM
my_films,
JSON_TABLE ( js, '$.favorites[*]'
COLUMNS (
id FOR ORDINALITY,
kind text PATH '$.kind',
NESTED PATH '$.films[*]' COLUMNS (
title text FORMAT JSON PATH '$.title' OMIT QUOTES,
director text PATH '$.director' KEEP QUOTES))) AS jt;
id | kind | title | director ----+----------+-----------------+-------------------- 1 | comedy | Bananas | "Woody Allen" 1 | comedy | The Dinner Game | "Francis Veber" 2 | horror | Psycho | "Alfred Hitchcock" 3 | thriller | Vertigo | "Alfred Hitchcock" 4 | drama | Yojimbo | "Akira Kurosawa" (5 rows)
Ниже показан другой запрос, использующий в качестве входных данных иной JSON
объект. В нем демонстрируется применение «соединения смежных элементов» (sibling join) через оператор UNION между
NESTED путями $.movies[*] и
$.books[*] а также использование
FOR ORDINALITY столбца на NESTED
уровнях (столбцы movie_id, book_id,
и author_id):
SELECT * FROM JSON_TABLE (
'{"favorites":
{"movies":
[{"name": "One", "director": "John Doe"},
{"name": "Two", "director": "Don Joe"}],
"books":
[{"name": "Mystery", "authors": [{"name": "Brown Dan"}]},
{"name": "Wonder", "authors": [{"name": "Jun Murakami"}, {"name":"Craig Doe"}]}]
}}'::json, '$.favorites[*]'
COLUMNS (
user_id FOR ORDINALITY,
NESTED '$.movies[*]'
COLUMNS (
movie_id FOR ORDINALITY,
mname text PATH '$.name',
director text),
NESTED '$.books[*]'
COLUMNS (
book_id FOR ORDINALITY,
bname text PATH '$.name',
NESTED '$.authors[*]'
COLUMNS (
author_id FOR ORDINALITY,
author_name text PATH '$.name'))));
user_id | movie_id | mname | director | book_id | bname | author_id | author_name
---------+----------+-------+----------+---------+---------+-----------+--------------
1 | 1 | One | John Doe | | | |
1 | 2 | Two | Don Joe | | | |
1 | | | | 1 | Mystery | 1 | Brown Dan
1 | | | | 2 | Wonder | 1 | Jun Murakami
1 | | | | 2 | Wonder | 2 | Craig Doe
(5 rows)