2016-05-21 14 views
1

Ich habe eine TabelleWie man ein JSONB-Array abfragt?

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

custom ein Array von JSON Objekte des Formulars {field:string, value:string} ist. Beispiel:

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

sagen, ich will alle oder mehrere der Visitors mit 3 finden apps_created, wie würde ich über diese gehen? Hinweis: Jeder Visitor kann verschiedene Felder haben und oft gibt es keine Überschneidung mit anderen Besuchern.

Ich habe versucht, die postgres Dokumentation oder andere stackoverflow Fragen zu konsultieren, aber ich habe eine harte Zeit herauszufinden, welche Funktionen/Operatoren in dieser Situation verwendet werden.

Jede Hilfe ist viel

+0

man viel machen das Leben könnte einfacher, indem Sie {'apps_created': '3'} speichern, dh das 'Feld' und den 'Wert' aus jedem Wörterbuch löschen, so dass Sie anstelle eines Wörterbuchs mit zwei Elementen ein Wörterbuch mit einem haben. In der Tat, wenn Sie das getan haben, könnten Sie in der Lage sein, die ganze Reihe von Wörterbüchern Ding und haben ein großes Wörterbuch, das so viel einfacher sein würde, in PostgreSQL und in Ihrem Code zu arbeiten – e4c5

+0

Der Grund für die Speicherung auf diese Weise ist, weil ich lassen Benutzer senden benutzerdefinierte Datenfelder/Werte und können sie daher zur Entwurfszeit nicht kennen. AFAIK das ist nicht möglich, wenn der Schlüssel wie das hardcoding – Tarlen

+0

Mit meinem Vorschlag müssen Sie immer noch nicht wissen, was diese Felder zur Entwurfszeit sind. – e4c5

Antwort

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

Upd
jedoch die klassische Art und Weise ist, solche Dinge in relationalen Datenbanken zu implementieren geschätzt (schematisch):

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

Super, danke. Kannst du die 't (x)' Syntax erklären? Ich stelle fest, dass es x jedem Element des Arrays zuordnet, aber eine kurze Ausarbeitung würde sehr geschätzt werden – Tarlen

+0

Auch in Bezug auf die Indizierung dieser Abfrage, ist ein GIN-Index auf Feld und dann Wert der Weg zu gehen? – Tarlen

+0

@Tarlen 1) Dies ist die Standard-Syntax für Unterabfragen in der from-Klausel, wobei "t" ein Alias ​​für Unterabfragen und optionale Aliase für Felder in eckigen Klammern ist: '... von (wählen Sie 1 als x) t' oder' .. . aus (wählen Sie 1) t (x) '. In unserem Fall ist 'unnest (custom)' gleich '(wählen Sie unnest (custom))'; 2) Ich habe niemals GIN-Indizes verwendet. – Abelisto

Verwandte Themen