2016-05-21 5 views
1

У меня есть таблицаКак запросить массив JSONB?

Visitor: (id, .., custom::jsonb[])

custom представляет собой массив объектов JSON вида {field:string, value:string}. Пример:

{"field": "apps_created", "value": "3"}

Скажем, я хочу, чтобы найти все Visitors с 3 или более apps_created, как я бы об этом? Примечание: каждый Visitor может иметь разные поля и часто не перекрывается с другими посетителями.

Я попытался проконсультироваться с документацией postgres или другими вопросами, касающимися stackoverflow, но мне сложно определить, какие функции/операторы используются в этой ситуации.

Любая помощь очень ценится

+0

вы могли бы сделать жизнь намного Сохранить {'apps_created': '3'}, т.е. сбросить 'поле' и 'значение' из каждого словаря, чтобы вместо словаря с двумя элементами у вас был словарь с одним. Фактически, если бы вы это сделали, вы могли бы вытащить весь массив словарей и иметь большой словарь, с которым было бы гораздо легче работать в postgresql и в вашем коде. – e4c5

+0

Причина его сохранения в том, что я позволяю пользователи представляют пользовательские поля данных/значения и, следовательно, не могут знать их во время разработки. AFAIK это невозможно, когда hardcoding такой ключ – Tarlen

+0

С моим предложением вам все равно не нужно знать, что эти поля находятся во время разработки. – e4c5

ответ

1
select * 
from visitor 
where 
    exists (
    select 1 
    from unnest(custom) t(x) 
    where x->>'field' = 'apps_created' and (x->>'value')::int >= 3); 

U pd,
Однако классический способ реализовать такие вещи в реляционных базах данных (схему):

create table entity (
    entity_id serial not null primary key, 
    ...); 

create table param (
    param_id serial not null primary key, 
    param_name varchar not null unique, 
    ...); 

create table param_value (
    param_id int references param(param_id), 
    entity_id int references entity(entity_id) on delete cascade, 
    value varchar, 
    ... 
    primary key (param_id, entity_id)); 
+0

Удивительный, спасибо. Можете ли вы объяснить синтаксис 't (x)'? Я полагаю, что он сопоставляет x каждому элементу массива, но краткая разработка будет очень полезна. – Tarlen

+0

Также, что касается индексации этого запроса, это индекс GIN в поле, а затем оценить способ его перемещения? – Tarlen

+0

@Tarlen 1) Это стандартный синтаксис для подзапросов в предложении from, где 't' является псевдонимом для подзапроса и необязательных псевдонимов для полей в скобках:' ... from (select 1 as x) t' или '.. . из (выберите 1) t (x) '. В нашем случае 'unsest (custom)' равно '(select unsest (custom))'; 2) Я никогда не использовал индексы GIN. – Abelisto

Смежные вопросы