2016-07-05 1 views
0

Учитывая структуру данных следующим образом:Выбор для массива Jsonb содержит регулярное выражение матч

{"single":"someText", "many":["text1", text2"]} 

Я могу запросить регулярное выражение на сингл с

WHERE JsonBColumn ->> 'single' ~ '^some.*' 

И я могу запросить а содержит матч на массив с

WHERE JsonBColumn -> 'many' ? 'text2' 

То, что я хотел бы сделать, это сделать содержит матч с регулярным выражением на JArray

ответ

2

Использовать jsonb_array_elements_text() в боковом соединении.

with the_data(id, jsonbcolumn) as (
    values 
     (1, '{"single":"someText", "many": ["text1", "text2"]}'::jsonb) 
    ) 

select distinct on (id) d.* 
from 
    the_data d, 
    jsonb_array_elements_text(jsonbcolumn->'many') many(elem) 
where elem ~ '^text.*'; 

id |     jsonbcolumn      
----+---------------------------------------------------- 
    1 | {"many": ["text1", "text2"], "single": "someText"} 
(1 row) 

См. Также this answer.


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

create or replace function jsonb_array_regex_like(json_array jsonb, pattern text) 
returns boolean language sql as $$ 
    select bool_or(elem ~ pattern) 
    from jsonb_array_elements_text(json_array) arr(elem) 
$$; 

Функция, безусловно, упрощает код:

with the_data(id, jsonbcolumn) as (
    values 
     (1, '{"single":"someText", "many": ["text1", "text2"]}'::jsonb) 
    ) 

select * 
from the_data 
where jsonb_array_regex_like(jsonbcolumn->'many', '^text.*'); 
0

я обнаружил, что это также можно преобразовать весь массив JSONB в текстовую строку и просто выполнить регулярное выражение. Побочный эффект, однако, что поиск на что-то вроде

ХТ 1" , «текст

бы в конечном итоге соответствия.

Этот подход не так чист, так как он не выполняет поиск по каждому элементу индивидуально, но выполняет работу с помощью более простого визуального описания.

WHERE JsonBColumn ->>'many' ~ 'text2' 
Смежные вопросы