2013-04-18 6 views
15

Ich habe eine TEXT Spalte mit gültigen JSON-Zeichenfolge.PostgreSQL 9.2 - Konvertieren TEXT JSON Zeichenfolge, um JSON/Hstore

CREATE TABLE users(settings TEXT); 

INSERT INTO users VALUES ('{"language":"en","gender":"male"}'); 
INSERT INTO users VALUES ('{"language":"fr","gender":"female"}'); 
INSERT INTO users VALUES ('{"language":"es","gender":"female"}'); 
INSERT INTO users VALUES ('{"language":"en","gender":"male"}'); 

Ich möchte einige Felder in ein Abfrageformat umwandeln.

Ein REGEXP_REPLACE für jedes Feld würde tun (language Feld und gender Feld). Aber da es gültige JSON, ist es Art und Weise zu:

  • Konvertieren in das JSON-Typ
  • Konvertieren in hstore Typ
  • oder jede andere gangbare Wege

SQLFiddle: http://sqlfiddle.com/#!12/54823

+2

Gewünscht Funktionalität ist eine von interessanten Features 9.3. Ich lese einige Artikel, wo beschrieben wurde mit pl/js8 für diesen Zweck http://www.postgresonline.com/journal/archives/263-PLV8JS-and-PLCoffee-Part-2-JSON-search-requests.html –

+0

Danke. Ich entdeckte auch, dass ich das erste tun kann, indem ich es einfach in JSON umwandele: 'settings :: json'. Aber es ist nicht abfragbar. Abgestimmt mit regexp. – huy

+0

FYI gibt es einen Backport von 9.3 JSON Funktionserweiterungen für PostgreSQL 9.2 http://adpgtech.blogspot.co.nz/2013/04/backport-of-93-json-enhancements.html –

Antwort

3

Wenn Sie benötigen einen Index, erstellen eine unveränderliche Funktion, die den JSON als Eingabe verwendet und das gewünschte Feld als Ausgabe in einer PL-Sprache liefert, zB:

create function extract_language(text) returns text as $$ 
    -- parse $1 as json 
    -- return $1.language 
$$ language whatever immutable; 

Dann einen Index für den Ausdruck hinzu:

create index users_language on users(extract_language(settings)); 

Der Index wird dann (möglicherweise) in Abfragen gewöhnen, wie:

select * from users where extract_language(settings) = 'en'; 
16
SELECT cast(settings AS json) from users; 
+0

Ich brauchte genau das gleiche. Das hat die Arbeit gut gemacht. Das heißt, ich kann nicht dafür sprechen, wie leistungsfähig es ist, obwohl ich einen relativ kleinen Datensatz abfrage. – slant

11

Oder in einem kürzesten Weg als Reza:

SELECT settings::json FROM users; 
Dann werden 10

, zur Auswahl von Sprache zum Beispiel:

SELECT settings::json->>'language' FROM users; 

Mehr Details über die official documentation.

+1

Ich weiß, das ist ruhig alt, aber: Wie kann ich nach einem speziellen Feld im Text suchen, sagen wir WHERE-Einstellungen :: json = 'team_id': team_id (so nach einem bestimmten Feld im Text der Einstellungen suchen) – Pille