Обход запросом структуры JSONB
#40138244
Ссылка:
Ссылка на сообщение:
Ссылка с названием темы:
Ссылка на профиль пользователя:
|
Участник
Откуда: Изнутри
Сообщения: 1
|
|
Если кому пригодится, обход структуры JSON и выдача скалярных значений с путями в порядке их следования 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26.
with recursive JSON_data (path, seq, value) as ( -- обход структуры JSON. Стартовый шаг
Select ARRAY[]::TEXT[] -- массив path, тут будем накапливать путь к данным. Ключи объектов или индексы в массивах
, ARRAY[]::bigint[] -- массив seq, Порядок следования на каждом уровне вложенности
, '{"A":"B", "C":5, "M":[2, "3", {"D":{"k":false, "m":"Ok"}, "E":null}]}'::jsonb -- собственно, сама структура JSON
union all -- очередной шаг. В JSON_data кусок JSON, который мы сейчас разбираем
(with JSA as (Select * from JSON_data) -- это извращение пришлось применить, поскольку JSON_data должно упоминаться один раз
select path||a.key -- прибавляем к пути ключ объекта
, JSA.seq||(row_number() over ()) -- Помещаем в последний уровень массива seq номер по порядку элемента объекта JSON
, a.value -- значение очередного элемента объекта JSON
from JSA -- то же самое, что JSON_data
, jsonb_each(JSA.value) a -- Обход всех элементов объекта
where JSA.value @> '{}' -- Разбираемый кусок JSON представляет собой объект
union all
select path||(row_number() over () - 1)::text -- прибавляем к пути позицию в массиве
, JSA.seq||(row_number() over ()) -- Помещаем в последний уровень массива seq номер по порядку элемента массива JSON
, b.value -- значение очередного элемента массива JSON
from JSA -- то же самое, что JSON_data
, jsonb_array_elements(JSA.value) b -- Обход всех элементов массива
where JSA.value @> '[]' -- Разбираемый кусок JSON представляет собой массив
)
)
Select path "Путь", value "Значение"
from JSON_data -- тут получаем все элементы (и узлы и листья) JSON структуры
where not value @> '[]' -- выдаём не массивы и не объекты. Иными словами, только листовые элементы,
and not value @> '{}' -- которые могут быть: строками, числами, false/true и null
order by seq -- упорядочиваем получаемые элементы JSON структуры в порядке их следования
Возможно, есть способ проще и я ломлюсь в открытую дверь?
|
|