Привет, Я DocuDroid!
Оценка ИИ поиска
Спасибо за оценку нашего ИИ поиска!
Мы будем признательны, если вы поделитесь своими впечатлениями, чтобы мы могли улучшить наш ИИ поиск для вас и других читателей.
GitHub

Работа с данными JSON

Андрей Аксенов

Greengage DB поддерживает типы JSON и JSONB для работы с данными в формате JSON. Обычно они используются для хранения результатов API-запросов, логов приложений, конфигурационных данных и другой полуструктурированной информации, которая не имеет естественного соответствия реляционной структуре.

Greengage DB реализует JSON в соответствии со спецификацией RFC 7159 и проверяет входные данные на соответствие правилам формата JSON. Некорректный JSON-текст отклоняется при выполнении операций вставки или обновления.

Greengage DB также предоставляет набор функций и операторов JSON для извлечения полей, фильтрации данных, преобразования JSON-структур, а также создания JSON-объектов и массивов. Узнайте больше в разделе Операторы и функции JSON.

Для выполнения команд, описанных в следующих разделах, подключитесь к мастер-хосту Greengage DB с помощью psql, как описано в статье Подключение к Greengage DB с использованием psql. Затем создайте новую базу данных и подключитесь к ней:

CREATE DATABASE marketplace;
\c marketplace

Обзор

О работе с JSON

Greengage DB поддерживает два типа данных JSON: JSON и JSONB. Оба типа принимают одинаковые значения, но различаются способом хранения и производительностью:

  • JSON сохраняет исходный текст без изменений.

    Сохраняются все пробелы, порядок ключей и дубликаты ключей. Если в объекте присутствуют дубликаты, функции обработки JSON используют последнее значение для повторяющихся ключей. Поскольку данные JSON при каждом обращении нужно анализировать заново, операции выполняются медленнее.

  • JSONB хранит JSON в двоичном формате, используя предварительно разобранное представление для ускорения операций.

    Пробелы удаляются, порядок ключей игнорируется, а при дублировании ключей сохраняется только последнее значение. Ввод данных в формате JSONB немного медленнее, чем в JSON, зато последующие операции над JSONB значительно быстрее, поскольку разбор структуры выполняется только один раз. Тип JSONB также поддерживает индексацию.

В большинстве случаев следует использовать JSONB, за исключением ситуаций, когда необходимо сохранить исходное форматирование или порядок ключей.

Кодировка JSON и JSONB

Документ RFC 7159 допускает наличие в строках JSON управляющих последовательностей Unicode, обозначаемых как \uXXXX. Однако в Greengage DB для каждой базы данных допускается только одна кодировка символов. Тип данных JSON не может полностью соответствовать спецификации JSON, если кодировка базы данных отличается от UTF-8. Попытки вставить символы, которые невозможно представить в выбранной кодировке базы данных, завершатся ошибкой. Символы, которые могут быть представлены в кодировке базы данных, но отсутствующие в UTF-8, допускаются.

  • Функция ввода для данных JSON принимает управляющие последовательности Unicode независимо от кодировки базы данных и проверяет только корректность их синтаксиса (\u, за которым следуют четыре шестнадцатеричные цифры).

  • Функция ввода для данных JSONB более строго контролирует ввод:

    • Не-ASCII символы (U+0080 и выше) допускаются, только если кодировка базы данных UTF-8.

    • Символы \u0000 отклоняются.

    • Суррогатные пары Unicode должны быть корректными; допустимые последовательности преобразуются в эквивалентные символы ASCII или UTF-8 для хранения.

Многие JSON-функции автоматически преобразуют управляющие последовательности Unicode в обычные символы. Если символ невозможно представить в кодировке базы данных, функция выдаст ошибку. Чтобы избежать проблем, не используйте управляющие последовательности Unicode вместе с кодировкой базы данных, отличной от UTF-8.

Пример:

Данная команда пытается привести JSON-литерал, содержащий знак авторского права, к типу JSONB:

SELECT '{ "a": "the Copyright \u00A9 sign" }'::jsonb;

В базе данных с кодировкой LATIN1 эта команда выдаст следующую ошибку:

ERROR:  unsupported Unicode escape sequence

Преобразование в JSONB

При преобразовании JSON-текста в JSONB примитивные типы JSON сопоставляются с соответствующими типами Greengage DB, как показано в таблице ниже. JSONB накладывает некоторые дополнительные ограничения, связанные с возможностями типов данных Greengage DB. Например, JSONB отклоняет числовые значения, выходящие за пределы диапазона, поддерживаемого типом NUMERIC в Greengage DB.

Примитивный тип JSON Тип Greengage DB Примечание

string

text

JSONB не допускает символ \u0000 и управляющие последовательности Unicode для символов, которые не поддерживаются кодировкой базы данных

number

numeric

Значения NaN и Infinity не разрешены

boolean

boolean

Значения true и false допускаются только в нижнем регистре

null

(отсутствует)

Представляет JSON null, являющийся типизированным значением внутри документа и отличающийся от SQL NULL, который обозначает отсутствие значения. При извлечении JSON null как JSON-значения (->) возвращается JSON null, а при извлечении как текста (->>) — пустая строка

Создание таблицы для JSON-данных

Для того чтобы сохранять JSON-документы, создайте таблицу со столбцом типа JSON или JSONB. Пример ниже показывает создание таблицы customer_profiles, в которой каждый профиль клиента хранится в виде документа JSONB:

CREATE TABLE customer_profiles
(
    profile JSONB
)
    WITH (appendoptimized = true)
    DISTRIBUTED RANDOMLY;

Узнайте больше про определение таблиц в статье Обзор таблиц.

Загрузка JSON-данных

Для эффективной вставки больших объемов JSON-данных используйте внешние таблицы или команду COPY. Подробнее о массовой загрузке данных смотрите в следующих статьях:

Оптимизированные для добавления (AO) таблицы предназначены для массовой загрузки данных, поэтому использование одиночных команд INSERT для них не рекомендуется.

Следующий файл customers.jsonl содержит по одному JSON-объекту на строку; каждый объект представляет собой профиль клиента:

{"id": "c001", "name": "Alice Johnson", "email": "alice@example.com", "active": true, "registered": "2020-01-15", "tags": {"membership": ["premium", "newsletter"], "region": "US"}}
{"id": "c002", "name": "Bob Smith", "email": "bob@example.com", "active": false, "registered": "2019-06-30", "tags": {"membership": ["trial"], "region": "EU"}}
{"id": "c003", "name": "Charlie Brown", "email": "charlie@example.com", "active": true, "registered": "2021-09-10"}
{"id": "c004", "name": "Diana Miller", "email": "diana@example.com", "tags": {"region": "UK", "membership": ["newsletter", "trial"]}}

Вы можете загрузить JSON-документы в таблицу напрямую из файла с помощью команды COPY:

COPY customer_profiles (profile)
    FROM '/home/gpadmin/examples/json/customers.jsonl';

Запросы к JSON-данным

Вы можете выполнять запросы к полям JSON с помощью операторов и функций JSON.

В примере ниже поля верхнего уровня извлекаются из JSON-документа с помощью оператора ->>:

SELECT profile ->> 'name'  AS name,
       profile ->> 'email' AS email
FROM customer_profiles;

Результат должен выглядеть так:

     name      |        email
---------------+---------------------
 Alice Johnson | alice@example.com
 Bob Smith     | bob@example.com
 Charlie Brown | charlie@example.com
 Diana Miller  | diana@example.com
(4 rows)

Вы можете обращаться к вложенным атрибутам в объектах JSON с помощью нескольких операторов -> и ->>: используйте -> для получения JSON-объекта или массива для дальнейшей навигации, а ->> — для извлечения конечного значения в виде обычного текста:

SELECT profile ->> 'name'             AS name,
       profile -> 'tags' ->> 'region' AS region
FROM customer_profiles;

Результат выглядит следующим образом:

     name      | region
---------------+--------
 Alice Johnson | US
 Bob Smith     | EU
 Charlie Brown |
 Diana Miller  | UK
(4 rows)

В качестве альтернативы можно использовать функцию jsonb_extract_path_text(), чтобы извлекать вложенные значения, указывая путь явно:

SELECT profile ->> 'name'                                 AS name,
       jsonb_extract_path_text(profile, 'tags', 'region') AS region_json
FROM customer_profiles;

Подробнее о получении строк из таблиц и представлений см. в статье Обзор команды SELECT.

Фильтрация JSON-данных

Вы можете фильтровать строки по значениям JSON-полей с помощью выражений WHERE или HAVING. Операторы JSON позволяют напрямую сравнивать поля, включая вложенные атрибуты.

Этот пример отбирает записи, где указанный ключ JSON верхнего уровня имеет заданное значение:

SELECT profile ->> 'name' AS name
FROM customer_profiles
WHERE profile ->> 'active' = 'true';

Результат:

     name
---------------
 Alice Johnson
 Charlie Brown
(2 rows)

В этом примере фильтрация выполняется по вложенному JSON-ключу:

SELECT profile ->> 'name' AS name
FROM customer_profiles
WHERE profile -> 'tags' ->> 'region' = 'US';

Результат должен выглядеть так:

     name
---------------
 Alice Johnson
(1 row)

Вы также можете приводить строковые значения JSON к нативным типам для сравнения:

SELECT profile ->> 'name' AS name
FROM customer_profiles
WHERE (profile ->> 'registered')::date > '2020-01-01';

Вывод выглядит следующим образом:

     name
---------------
 Alice Johnson
 Charlie Brown
(2 rows)

JSONB: проверки вхождения и существования

Тип JSONB поддерживает операции проверки вхождения и существования:

  • Проверка вхождения определяет, содержится ли один JSON-документ внутри другого,

  • Проверка существования определяет, присутствует ли заданный ключ или элемент массива на верхнем уровне JSON-значения.

В приведенном ниже примере используется оператор @> для получения строк, в которых столбец JSONB содержит указанный поддокумент:

SELECT profile ->> 'name' AS name
FROM customer_profiles
WHERE profile -> 'tags' @> '{"region": "EU"}';

Результат:

   name
-----------
 Bob Smith
(1 row)

Этот запрос возвращает строки, у которых JSON-объект верхнего уровня содержит указанный ключ:

SELECT profile ->> 'name' AS name
FROM customer_profiles
WHERE profile ? 'tags';

Результат выглядит следующим образом:

     name
---------------
 Alice Johnson
 Bob Smith
 Diana Miller
(3 rows)

Этот запрос возвращает строки, в которых JSON-объект содержит любой из указанных ключей:

SELECT profile ->> 'name' AS name
FROM customer_profiles
WHERE profile ?| ARRAY ['active', 'registered'];

Вывод выглядит следующим образом:

     name
---------------
 Charlie Brown
 Alice Johnson
 Bob Smith
(3 rows)

Индексация JSONB

JSONB поддерживает индексы GIN и B-дерево:

  • GIN-индексы эффективно выполняют поиск ключей или пар ключ/значение в большом количестве документов JSONB.

  • Индексы B-tree полезны в основном для сравнения или проверки равенства JSON-документов целиком.

GIN-индексы поддерживают два класса операторов для JSONB:

  • jsonb_ops — класс операторов GIN, используемый по умолчанию, который поддерживает запросы с операторами @>, ?, ?& и ?|. Этот класс обеспечивает большую гибкость, но может занимать больше места в индексе и имеет немного более низкую производительность для запросов на вхождение.

  • jsonb_path_ops — альтернативный класс операторов GIN, который поддерживает индексацию только для оператора @>. Индексируются только пути и значения, необходимые для проверки вхождения, что обеспечивает меньший размер индекса и более быстрый поиск.

Создайте GIN-индекс по столбцу profile в таблице customer_profiles:

CREATE INDEX profile_gin_idx ON customer_profiles USING gin (profile);

После создания индекса выполните ANALYZE, чтобы обновить статистику таблицы для планировщика запросов:

ANALYZE;

Проверьте, что индекс используется для поиска документов JSONB, соответствующих условию вхождения:

EXPLAIN (COSTS OFF)
SELECT profile ->> 'name' AS name
FROM customer_profiles
WHERE profile @> '{"active": false}';

Результат должен включать Bitmap Index Scan по индексу profile_gin_idx:

                               QUERY PLAN
-------------------------------------------------------------------------
 Gather Motion 4:1  (slice1; segments: 4)
   ->  Result
         ->  Bitmap Heap Scan on customer_profiles
               Recheck Cond: (profile @> '{"active": false}'::jsonb)
               ->  Bitmap Index Scan on profile_gin_idx
                     Index Cond: (profile @> '{"active": false}'::jsonb)
 Optimizer: Pivotal Optimizer (GPORCA)
(7 rows)

Операторы и функции JSON

Операторы JSON

Следующие операторы доступны для типов данных JSON и JSONB.

Получение элемента JSON-массива (→)

Оператор: ->

Тип правого операнда: int

Возвращает элемент JSON-массива по указанному индексу, начиная с нуля.

Пример:

SELECT '[
  {
    "id": 1,
    "name": "Alice"
  },
  {
    "id": 2,
    "name": "Bob"
  }
]'::jsonb -> 1;

Результат:

         ?column?
--------------------------
 {"id": 2, "name": "Bob"}
(1 row)

Получение поля JSON-объекта (→)

Оператор: ->

Тип правого операнда: text

Возвращает поле JSON-объекта по ключу.

Пример:

SELECT '{
  "user": {
    "name": "Alice",
    "email": "alice@example.com"
  }
}'::jsonb -> 'user';

Результат:

                    ?column?
-------------------------------------------------
 {"name": "Alice", "email": "alice@example.com"}
(1 row)

Получение элемента JSON-массива в виде текста (→>)

Оператор: ->>

Тип правого операнда: int

Возвращает элемент JSON-массива в виде текста.

Пример:

SELECT '[
  "apple",
  "banana",
  "cherry"
]'::jsonb ->> 1;

Результат:

 ?column?
----------
 banana
(1 row)

Получение поля JSON-объекта в виде текста (->>)

Оператор: ->>

Тип правого операнда: text

Возвращает поле JSON-объекта в виде текста.

Пример:

SELECT '{
  "product": "Book",
  "price": 9.99
}'::jsonb ->> 'product';

Результат:

 ?column?
----------
 Book
(1 row)

Получение JSON-объекта по указанному пути (#>)

Оператор: #>

Тип правого операнда: text[]

Возвращает JSON-объект по указанному пути.

Пример:

SELECT '{
  "customer": {
    "address": {
      "city": "Amsterdam",
      "zip": "1011AB"
    }
  }
}'::jsonb #> '{customer,address}';

Результат:

                ?column?
----------------------------------------
 {"zip": "1011AB", "city": "Amsterdam"}
(1 row)

Получение JSON-объекта по указанному пути в виде текста (#>>)

Оператор: #>>

Тип правого операнда: text[]

Возвращает JSON-объект по указанному пути в виде текста.

Пример:

SELECT '{
  "customer": {
    "address": {
      "city": "Amsterdam",
      "zip": "1011AB"
    }
  }
}'::jsonb #>> '{customer,address,city}';

Результат:

 ?column?
-----------
 Amsterdam
(1 row)

Операторы JSONB

Следующие операторы доступны только для значений типа JSONB. Многие из них могут быть проиндексированы с помощью классов операторов JSONB.

Вхождение (@>)

Оператор: @>

Тип правого операнда: JSONB

Проверяет, содержится ли правое JSON-значение внутри левого JSON-значения.

Пример:

SELECT '{
  "name": "Alice",
  "active": true,
  "role": "admin"
}'::jsonb @> '{
  "role": "admin"
}'::jsonb;

Результат:

 ?column?
----------
 t
(1 row)

Входит в (<@)

Оператор: <@

Тип правого операнда: JSONB

Проверяет, содержится ли левое JSON-значение внутри правого JSON-значения.

Пример:

SELECT '{
  "role": "admin"
}'::jsonb <@ '{
  "name": "Alice",
  "active": true,
  "role": "admin"
}'::jsonb;

Результат:

 ?column?
----------
 t
(1 row)

Существование ключа/элемента (?)

Оператор: ?

Тип правого операнда: text

Проверяет, существует ли указанный ключ или элемент в JSON-значении.

Пример:

SELECT '{
  "name": "Alice",
  "email": "alice@example.com"
}'::jsonb ? 'address';

Результат:

 ?column?
----------
 f
(1 row)

Существование любого ключа/элемента из перечисленных (?|)

Оператор: ?|

Тип правого операнда: text[]

Проверяет, существует ли хотя бы один из указанных ключей или элементов в JSON-значении.

Пример:

SELECT '{
  "name": "Alice",
  "email": "alice@example.com",
  "active": true
}'::jsonb ?| array ['phone','email'];

Результат:

 ?column?
----------
 t
(1 row)

Существование всех перечисленных ключей/элементов (?&)

Оператор: ?&

Тип правого операнда: text[]

Проверяет, существуют ли все указанные ключи или элементы.

Пример:

SELECT '{
  "name": "Alice",
  "email": "alice@example.com",
  "active": true
}'::jsonb ?& array ['phone','email'];

Результат:

 ?column?
----------
 f
(1 row)

Функции создания JSON

Этот раздел описывает функции, которые генерируют значения JSON. Хотя у этих функций нет отдельных версий для JSONB, их результаты можно привести к типу JSONB.

array_to_json()

Функция: array_to_json(anyarray [, pretty_bool])

Возвращает массив в виде JSON-массива. Многомерный массив преобразуется в JSON-массив массивов. Если параметр pretty_bool установлен в true, между элементами верхнего уровня добавляются переносы строки.

Пример:

SELECT array_to_json('{{10, 20}, {30, 40}}'::int[]);

Результат:

   array_to_json
-------------------
 [[10,20],[30,40]]
(1 row)

json_build_array()

Функция: json_build_array(VARIADIC "any")

Создает JSON-массив, элементы которого могут быть разных типов, из списка аргументов VARIADIC.

Пример:

SELECT json_build_array(1001, 'Alice', true, 89.5);

Результат:

      json_build_array
-----------------------------
 [1001, "Alice", true, 89.5]
(1 row)

json_build_object()

Функция: json_build_object(VARIADIC "any")

Создает JSON-объект из списка аргументов VARIADIC. Список аргументов обрабатывается по порядку и преобразуется в набор пар ключ/значение.

Пример:

SELECT json_build_object('id', 1001, 'name', 'Alice', 'active', true);

Результат:

                json_build_object
--------------------------------------------------
 {"id" : 1001, "name" : "Alice", "active" : true}
(1 row)

json_object(text[])

Функция: json_object(text[])

Создает JSON-объект из текстового массива. Массив должен быть одномерным или двумерным. Одномерный массив должен содержать четное число элементов. Элементы интерпретируются как пары ключ/значение.

Для двумерного массива каждый внутренний массив должен содержать ровно два элемента, которые рассматриваются как пара ключ/значение.

Пример 1:

SELECT json_object('{id, 1, name, "Book", price, "19.99"}');

Результат:

                   json_object
--------------------------------------------------
 {"id" : "1", "name" : "Book", "price" : "19.99"}
(1 row)

Пример 2:

SELECT json_object('{{id, 1}, {name, "Book"}, {price, "19.99"}}');

Результат:

                   json_object
--------------------------------------------------
 {"id" : "1", "name" : "Book", "price" : "19.99"}
(1 row)

json_object(text[], text[])

Функция: json_object(keys text[], values text[])

Создает JSON-объект из текстового массива. В этой форме json_object() ключи и значения берутся по парам из двух отдельных массивов. В остальном поведение совпадает с формой функции с одним аргументом.

Пример:

SELECT json_object('{id, name}', '{1, "Book"}');

Результат:

          json_object
-------------------------------
 {"id" : "1", "name" : "Book"}
(1 row)

row_to_json()

Функция: row_to_json(record [, pretty_bool])

Возвращает строку в виде JSON-объекта. Если параметр pretty_bool установлен в true, между элементами верхнего уровня добавляются переносы строки.

Пример:

SELECT row_to_json(row (10, 'Laptop'));

Результат:

       row_to_json
-------------------------
 {"f1":10,"f2":"Laptop"}
(1 row)

to_json()

Функция: to_json(anyelement)

Возвращает значение в виде JSON-объекта. Массивы и составные типы обрабатываются рекурсивно и преобразуются в массивы и объекты. Если входные данные содержат приведение типа к JSON, для преобразования используется функция приведения; в противном случае создается скалярное JSON-значение. Для всех скалярных типов, кроме числа, boolean-значения или null, используется текстовое представление с кавычками и экранированием, чтобы получилось корректное JSON-значение.

Пример:

SELECT to_json('Alice said "Hi!"'::text);

Результат:

       to_json
----------------------
 "Alice said \"Hi!\""
(1 row)

Агрегатные функции JSON

CREATE TABLE products
(
    id    SERIAL,
    name  VARCHAR(100),
    price DECIMAL(10, 2)
)
    WITH (appendoptimized = true)
    DISTRIBUTED BY (id);
INSERT INTO products (name, price)
VALUES ('Laptop', 999.99),
       ('Smartphone', 499.99),
       ('Headphones', 89.99);

json_agg()

Функция: json_agg(<record>)

Агрегирует записи в виде JSON-массива объектов.

Пример:

SELECT json_agg(name ORDER BY price DESC) AS product_names
FROM products;

Результат:

             product_names
----------------------------------------
 ["Laptop", "Smartphone", "Headphones"]
(1 row)

json_object_agg()

Функция: json_object_agg(name, value)

Агрегирует пары имя/значение в виде JSON-объекта.

Пример:

SELECT json_object_agg(id, name ORDER BY price DESC) AS products_map
FROM products;

Результат:

                        products_map
------------------------------------------------------------
 { "1" : "Laptop", "2" : "Smartphone", "3" : "Headphones" }
(1 row)

Функции обработки JSON

В этом разделе перечислены функции, доступные для обработки значений типов JSON и JSONB.

json_array_elements() / jsonb_array_elements()

Функция: json_array_elements(json), jsonb_array_elements(jsonb)

Тип возвращаемого значения: setof json, setof jsonb

Разворачивает JSON-массив в набор JSON-значений.

Пример:

SELECT *
FROM jsonb_array_elements('[
  {
    "name": "Alice"
  },
  {
    "name": "Bob"
  },
  {
    "name": "Carol"
  }
]');

Результат:

       value
-------------------
 {"name": "Alice"}
 {"name": "Bob"}
 {"name": "Carol"}
(3 rows)

json_array_elements_text() / jsonb_array_elements_text()

Функция: json_array_elements_text(json), jsonb_array_elements_text(jsonb)

Тип возвращаемого значения: setof text

Разворачивает JSON-массив в набор текстовых значений.

Пример:

SELECT *
FROM jsonb_array_elements_text('["Laptop","Smartphone","Headphones"]');

Результат:

   value
------------
 Laptop
 Smartphone
 Headphones
(3 rows)

json_array_length() / jsonb_array_length()

Функция: json_array_length(json), jsonb_array_length(jsonb)

Тип возвращаемого значения: int

Возвращает количество элементов в JSON-массиве верхнего уровня.

Пример:

SELECT json_array_length('[{"name":"Alice"},{"name":"Bob"},{"name":"Carol"}]');

Результат:

 json_array_length
-------------------
                 3
(1 row)

json_each() / jsonb_each()

Функция: json_each(json), jsonb_each(jsonb)

Тип возвращаемого значения: setof record со столбцами:

  • key text

  • value json (json_each) / value jsonb (jsonb_each)

Разворачивает JSON-объект верхнего уровня в набор пар ключ/значение.

Пример:

SELECT *
FROM json_each('{
  "product": "Laptop",
  "price": 999.99,
  "in_stock": true
}');

Результат:

   key    |  value
----------+----------
 product  | "Laptop"
 price    | 999.99
 in_stock | true
(3 rows)

json_each_text() / jsonb_each_text()

Функция: json_each_text(json), jsonb_each_text(jsonb)

Тип возвращаемого значения: setof record со столбцами:

  • key text

  • value text

Разворачивает JSON-объект верхнего уровня в набор пар ключ/значение. Возвращаемые значения будут иметь тип text.

Пример:

SELECT *
FROM json_each_text('{
  "product": "Laptop",
  "price": 999.99,
  "in_stock": true
}');

Результат:

   key    | value
----------+--------
 product  | Laptop
 price    | 999.99
 in_stock | true
(3 rows)

json_extract_path() / jsonb_extract_path()

Функция: json_extract_path(from_json json, VARIADIC path_elems text[]), jsonb_extract_path(from_json jsonb, VARIADIC path_elems text[])

Тип возвращаемого значения: JSON, JSONB

Возвращает JSON-значение, на которое указывает path_elems. Эквивалентно оператору #> (см. Получение JSON-объекта по указанному пути (#>)).

Пример:

SELECT jsonb_extract_path(
               '{
                 "order": {
                   "id": 123,
                   "customer": {
                     "name": "Alice",
                     "vip": true
                   }
                 }
               }',
               'order', 'customer'
       );

Результат:

       jsonb_extract_path
--------------------------------
 {"vip": true, "name": "Alice"}
(1 row)

json_extract_path_text() / jsonb_extract_path_text()

Функция: json_extract_path_text(from_json json, VARIADIC path_elems text[]), jsonb_extract_path_text(from_json jsonb, VARIADIC path_elems text[])

Тип возвращаемого значения: text

Возвращает JSON-значение, на которое указывает path_elems, в виде текста. Эквивалентно оператору #>> (см. Получение JSON-объекта по указанному пути в виде текста (#>>)).

Пример:

SELECT jsonb_extract_path_text(
               '{
                 "order": {
                   "id": 123,
                   "customer": {
                     "name": "Alice",
                     "vip": true
                   }
                 }
               }',
               'order', 'customer', 'name'
       );

Результат:

 jsonb_extract_path_text
-------------------------
 Alice
(1 row)

json_object_keys() / jsonb_object_keys()

Функция: json_object_keys(json), jsonb_object_keys(jsonb)

Тип возвращаемого значения: setof text

Возвращает набор ключей из JSON-объекта верхнего уровня.

Пример:

SELECT *
FROM json_object_keys('{
  "id": 1,
  "name": "Laptop",
  "price": 999.99
}');

Результат:

 json_object_keys
------------------
 id
 name
 price
(3 rows)

json_populate_record() / jsonb_populate_record()

Функция: json_populate_record(base anyelement, from_json json), jsonb_populate_record(base anyelement, from_json jsonb)

Тип возвращаемого значения: anyelement

Разворачивает объект из from_json в строку, столбцы которой соответствуют типу записи, определенному параметром base.

Пример:

CREATE TYPE product_info AS
(
    id    INT,
    name  TEXT,
    price NUMERIC
);

SELECT *
FROM json_populate_record(NULL::product_info,
                          '{
                            "id": 1,
                            "name": "Laptop",
                            "price": 999.99
                          }');

Результат:

 id |  name  | price
----+--------+--------
  1 | Laptop | 999.99
(1 row)

json_populate_recordset() / jsonb_populate_recordset()

Функция: json_populate_recordset(base anyelement, from_json json), jsonb_populate_recordset(base anyelement, from_json jsonb)

Тип возвращаемого значения: setof anyelement

Разворачивает внешний массив объектов из from_json в набор строк, столбцы которых соответствуют типу записи, определенному параметром base.

Пример:

CREATE TYPE item_info AS
(
    id  INT,
    qty INT
);

SELECT *
FROM json_populate_recordset(NULL::item_info,
                             '[
                               {
                                 "id": 1,
                                 "qty": 10
                               },
                               {
                                 "id": 2,
                                 "qty": 25
                               },
                               {
                                 "id": 3,
                                 "qty": 40
                               }
                             ]');

Результат:

 id | qty
----+-----
  1 |  10
  2 |  25
  3 |  40
(3 rows)

json_to_record() / jsonb_to_record()

Функция: json_to_record(json), jsonb_to_record(jsonb)

Тип возвращаемого значения: record

Создает произвольную запись из JSON-объекта. Как и для всех функций, возвращающих запись, вызывающий должен явно указать структуру записи с помощью ключевого слова AS.

Пример:

SELECT *
FROM json_to_record('{"id":1,"name":"Laptop","price":999.99}')
         AS x(id INT, name TEXT, price NUMERIC);

Результат:

 id |  name  | price
----+--------+--------
  1 | Laptop | 999.99
(1 row)

json_to_recordset() / jsonb_to_recordset()

Функция: json_to_recordset(json), jsonb_to_recordset(jsonb)

Тип возвращаемого значения: setof record

Создает произвольный набор записей из JSON-массива объектов. Как и для всех функций, возвращающих запись, вызывающий должен явно указать структуру записи с помощью ключевого слова AS.

Пример:

SELECT *
FROM json_to_recordset('[{"id":1,"name":"Laptop"},{"id":2,"name":"Smartphone"}]')
         AS x(id INT, name TEXT);

Результат:

 id |    name
----+------------
  1 | Laptop
  2 | Smartphone
(2 rows)

json_typeof() / jsonb_typeof()

Функция: json_typeof(json), jsonb_typeof(jsonb)

Тип возвращаемого значения: text

Возвращает тип JSON-значения верхнего уровня в виде строки. Возможные типы: object, array, string, number, boolean и null.

Значение null, возвращаемое функцией json_typeof(), не следует путать с SQL-значением NULL. Вызов json_typeof('null'::json) возвращает текстовое значение null, тогда как вызов json_typeof(NULL::json) возвращает SQL-значение NULL.

Пример:

SELECT json_typeof('{"name":"Alice"}'),
       json_typeof('["a","b","c"]'),
       json_typeof('123'),
       json_typeof('true');

Результат:

 json_typeof | json_typeof | json_typeof | json_typeof
-------------+-------------+-------------+-------------
 object      | array       | number      | boolean
(1 row)
ПРИМЕЧАНИЕ

Примеры функций json_populate_record(), json_populate_recordset(), json_to_record() и json_to_recordset() используют константные значения. На практике эти функции обычно применяются к столбцам типов JSON или JSONB из таблицы в конструкции FROM. Извлеченные значения ключей можно использовать в других частях запроса, например, в WHERE или в списке целевых столбцов. Извлечение нескольких значений одновременно обычно быстрее, чем использование отдельных операторов для каждого ключа.