Ich habe einen Tisch, an dem ich Informationen über meine Kaninchen speichern kann. Es sieht aus wie das:
create table rabbits (rabbit_id bigserial primary key, info json not null);
insert into rabbits (info) values
('{"name":"Henry", "food":["lettuce","carrots"]}'),
('{"name":"Herald","food":["carrots","zucchini"]}'),
('{"name":"Helen", "food":["lettuce","cheese"]}');
Wie soll ich die Kaninchen finden, die Karotten mögen? Ich habe mir das ausgedacht:
select info->>'name' from rabbits where exists (
select 1 from json_array_elements(info->'food') as food
where food::text = '"carrots"'
);
Ich mag diese Abfrage nicht. Es ist ein Chaos.
Als Vollzeit-Kaninchenhalter habe ich keine Zeit, mein Datenbankschema zu ändern. Ich möchte nur meine Kaninchen richtig füttern. Gibt es eine besser lesbare Möglichkeit, diese Abfrage durchzuführen?
json
postgresql
postgresql-9.3
Schneeball
quelle
quelle
Antworten:
Ab PostgreSQL 9.4 können Sie den
?
Operator verwenden :Sie können die
?
Abfrage sogar für den"food"
Schlüssel indizieren, wenn Sie stattdessen zum Typ jsonb wechseln :Natürlich haben Sie als Vollzeit-Kaninchenhalter wahrscheinlich keine Zeit dafür.
Update: Hier ist eine Demonstration der Leistungsverbesserungen an einem Tisch mit 1.000.000 Kaninchen, an dem jedes Kaninchen zwei Lebensmittel mag und 10% davon Karotten mögen:
quelle
select * from rabbits where info->'food' != '[]';
create table t (x jsonb); insert into t (x) values ('[1,2,3]'), ('[2,3,4]'), ('[3,4,5]'); select * from t where x @> '2';
. Beachten Sie, dass dies'2'
eine JSON-Nummer ist. Lassen Sie sich nicht von den Zitaten irreführen.Sie könnten den Operator @> verwenden, um so etwas zu tun
quelle
'
Zecken um "Karotten" ... es bricht, wenn Sie diese weglassen, auch wenn Sie nach einer ganzen Zahl suchen. (verbrachte 3 Stunden damit, eine ganze Zahl zu finden, damit sie auf magische Weise funktioniert, indem'
Zecken um die Zahl'
, um eine Zeichenfolge zu bilden, da alles eine Zeichenfolge für SQL im JSONB-Typ ist. Zum Beispiel boolean :'true'
, string :'"example"'
, integer :'123'
.Nicht schlauer, aber einfacher:
quelle
Eine kleine Variation, aber nichts Neues. Es fehlt wirklich eine Funktion ...
quelle