Wie frage ich mithilfe von Feldern im neuen PostgreSQL JSON-Datentyp ab?


216

Ich suche nach einigen Dokumenten und / oder Beispielen für die neuen JSON-Funktionen in PostgreSQL 9.2.

Insbesondere bei einer Reihe von JSON-Datensätzen:

[
  {name: "Toby", occupation: "Software Engineer"},
  {name: "Zaphod", occupation: "Galactic President"}
]

Wie würde ich die SQL schreiben, um einen Datensatz nach Namen zu finden?

In Vanilla SQL:

SELECT * from json_data WHERE "name" = "Toby"

Das offizielle Entwicklerhandbuch ist ziemlich spärlich:

Update I.

Ich habe eine Übersicht zusammengestellt, die ausführlich beschreibt, was derzeit mit PostgreSQL 9.2 möglich ist . Mit einigen benutzerdefinierten Funktionen können Sie Folgendes tun:

SELECT id, json_string(data,'name') FROM things
WHERE json_string(data,'name') LIKE 'G%';

Update II

Ich habe jetzt meine JSON-Funktionen in ein eigenes Projekt verschoben:

PostSQL - eine Reihe von Funktionen zur Umwandlung von PostgreSQL und PL / v8 in einen fantastischen JSON-Dokumentenspeicher


3
Erst vor kurzem fand ich diesen Blog - Post von Matt Schinckel, die im Detail erklärt JSON in PostgreSQL Abfragen schinckel.net/2014/05/25/querying-json-in-postgres
— Knowbody

1
@knowbody In diesem Beitrag geht es eigentlich darum, JSONB abzufragen, was sich deutlich von JSON unterscheidet. Mein schlechtes, weil ich das in der Post nicht klarer gemacht habe.
— Matthew Schinckel

Antworten:


177

Postgres 9.2

Ich zitiere Andrew Dunstan auf der Liste der pgsql-Hacker :

Irgendwann wird es möglicherweise einige json-verarbeitende Funktionen geben (im Gegensatz zu json-produzierenden), aber nicht in 9.2.

Verhindert nicht, dass er eine Beispielimplementierung in PLV8 bereitstellt , die Ihr Problem lösen sollte.

Postgres 9.3

Bietet ein Arsenal neuer Funktionen und Operatoren, um "json-processing" hinzuzufügen.

Die Antwort auf die ursprüngliche Frage in Postgres 9.3:

SELECT *
FROM   json_array_elements(
  '[{"name": "Toby", "occupation": "Software Engineer"},
    {"name": "Zaphod", "occupation": "Galactic President"} ]'
  ) AS elem
WHERE elem->>'name' = 'Toby';

Erweitertes Beispiel:

Bei größeren Tabellen möchten Sie möglicherweise einen Ausdrucksindex hinzufügen, um die Leistung zu steigern:

Postgres 9.4

Adds jsonb(b für "binär", Werte werden als native Postgres-Typen gespeichert) und noch mehr Funktionalität für beide Typen. Zusätzlich zu den oben erwähnten Expressionsindizes werden jsonbauch GIN-, btree- und Hash-Indizes unterstützt, wobei GIN der wirksamste davon ist.

Das Handbuch geht so weit, Folgendes vorzuschlagen:

Im Allgemeinen sollten die meisten Anwendungen es vorziehen, JSON-Daten als zu speichern jsonb , es sei denn, es gibt ganz spezielle Anforderungen, wie z. B. ältere Annahmen zur Reihenfolge der Objektschlüssel.

Meine kühne Betonung.

Die Leistung profitiert von allgemeinen Verbesserungen der GIN-Indizes.

Postgres 9.5

Komplette jsonbFunktionen und Bediener. Fügen Sie weitere Funktionen hinzu, die Sie jsonban Ort und Stelle bearbeiten und anzeigen können.


1
Vielen Dank, ich bin mit dem PLV8-Ansatz sehr schnell auf Typprobleme gestoßen. Sieht vielversprechend aus, ist aber momentan nicht wirklich brauchbar.
— Toby Hede

@TobyHede: Dann müssen wir wohl auf 9.3 warten.
— Erwin Brandstetter

1
@ JoeShaw: Danke, ich habe entsprechend aktualisiert und einen Link zum Postgres-Wiki hinzugefügt.
— Erwin Brandstetter

@ErwinBrandstetter wenn ich nach WHERE elem suche - >> 'korrekt' = 'WAHR'; und der JSON sieht folgendermaßen aus: "richtig": "WAHR", wie kann man logische Begriffe richtig abfragen?
— Shiraj

@ Shiraj: Bitte stellen Sie die neuen Fragen als Frage . Kommentare sind nicht der richtige Ort.
— Erwin Brandstetter

87

Verwenden Sie bei Postgres 9.3+ einfach den ->Operator. Beispielsweise,

SELECT data->'images'->'thumbnail'->'url' AS thumb FROM instagram;

Unter http://clarkdave.net/2013/06/what-can-you-do-with-postgresql-and-json/ finden Sie einige schöne Beispiele und ein Tutorial.


2
Im obigen Beispiel sollte ein Feld datamit einem JSON-Dokument benannt sein : {images:{thumbnail:{url:'thumbnail.jpg'}}}. Lassen Sie uns wissen, wie Ihre Daten aussehen und welche Abfrage fehlschlägt.
— Meekohi


6
Wie können Sie abfragen, ob ein Array vorhanden ist? Ich sehe den Operator # >>, aber keine Ahnung, wie man ihn benutzt!
— Mohamed El Mahallawy

Kann ich in dieser Auswahlabfrage einen Platzhalter verwenden? DhSELECT data->'%'->'thumbnail'->'url' AS thumb FROM instagram;
— Bharat

@ Meekohis Antwort funktioniert gut: Insbesondere brauchte ich nicht ::jsonwie in anderen Beiträgen beschrieben. Beachten Sie auch, dass der ->Bediener einen Fehler ausgibt, wenn Sie versuchen, auf eine Eigenschaft zuzugreifen, die nicht vorhanden ist (dh wenn Sie JSON versetzt haben):ERROR: column "jsonPropertyYouWant" does not exist
— Die rote Erbse

19

Verwenden Sie mit postgres 9.3 -> für den Objektzugriff. 4 Beispiel

seed.rb

se = SmartElement.new
se.data = 
{
    params:
    [
        {
            type: 1,
            code: 1,
            value: 2012,
            description: 'year of producction'
        },
        {
            type: 1,
            code: 2,
            value: 30,
            description: 'length'
        }
    ]
}

se.save

Schienen c

SELECT data->'params'->0 as data FROM smart_elements;

kehrt zurück

                                 data
----------------------------------------------------------------------
 {"type":1,"code":1,"value":2012,"description":"year of producction"}
(1 row)

Sie können weiter verschachteln

SELECT data->'params'->0->'type' as data FROM smart_elements;

Rückkehr

 data
------
 1
(1 row)
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.