UPDATE: Благодаря therealgaxbo на Reddit, мы начали с моим оригинальным кодом и разработали что-то более краткое:
with recursive deconstruct (jsonlevel) as(
values ('{"id":1,"children":[{"id":2},{"id":3,"children":[{"id":4}]}]}'::json)
union all
select
case left(jsonlevel::text, 1)
when '{' then (json_each(jsonlevel)).value
when '[' then json_array_elements(jsonlevel)
end as jsonlevel
from
deconstruct
where
left(jsonlevel::text, 1) in ('{', '[')
)
select * from deconstruct where case when left(jsonlevel::text, 1) = '{' then jsonlevel->>'id' = '4' else false end;
Моего первоначальный ответ ниже:
Я экспериментировал, как сумасшедшие и, наконец, придумал с чем-то вроде этого:
with recursive ret(jsondata) as
(select row_to_json(col)::text jsondata from
json_each('{
"id":1,
"children": [
{ "id":2 },
{ "id": 3, "children": [
{ "id": 4 }
]
}
]
}'::json) col
union
select case when left(jsondata::text,1)='[' then row_to_json(json_each(json_array_elements(jsondata)))::text
when left((jsondata->>'value'),2)='{}' then null::text
when left((jsondata->>'value')::text,1)='[' then row_to_json(json_each(json_array_elements(jsondata->'value')))::text
else ('{"key":'||(jsondata->'key')||', "value":'||(jsondata->'value')||'}')::json::text end jsondata
from (
select row_to_json(json_each(ret.jsondata::json)) jsondata
from ret) xyz
)
select max(1) from ret
where jsondata::json->>'key'='id'
and jsondata::json->>'value'='1'
К сожалению, я попытался решить эту проблему с помощью 9.3, однако я столкнулся с проблемами с получением s ame для запуска на объектах и массивах. На самом деле я думаю, что в 9.4 это может быть намного проще. Я начал писать рекурсивный запрос, чтобы сделать это, но, увы, я потерпел неудачу - на сегодняшний день. –
Ну, конечно, я понял, что взломать, было ли поле json массивом или объектом на основе первого символа его текстового представления. –
Не можете напрямую ответить на ваш вопрос, но я использую JSONSelect и PLV8 для обработки моих более сложных задач обхода JSON и запросов. Потратил некоторое время, чтобы настроить, но он работает хорошо для нас. – trvrm