Postgresql: Sie Finden die Werte im JSON-array als Platzhalter und Vergleichsoperatoren mit index

Ich habe eine Tabelle mit JSON-array-Daten möchte ich suchen.

CREATE TABLE data (id SERIAL, json JSON);

INSERT INTO data (id, json) 
  VALUES (1, '[{"name": "Value A", "value": 10}]');

INSERT INTO data (id, json) 
  VALUES (2, '[{"name": "Value B1", "value": 5}, {"name": "Value B2", "value": 15}]');

Wie beschrieben in diese Antwort, ich habe eine Funktion, die es erlaubt, auch erstellen Sie einen index für das array Daten (wichtig).

CREATE OR REPLACE FUNCTION json_val_arr(_j json, _key text)
  RETURNS text[] AS
$$
SELECT array_agg(elem->>_key)
FROM   json_array_elements(_j) AS x(elem)
$$
  LANGUAGE sql IMMUTABLE;

Dies funktioniert gut, wenn ich will, zu finden, die einen gesamten Wert (zB. "Wert B1"):

SELECT *
FROM data
WHERE '{"Value B1"}'::text[] <@ (json_val_arr(json, 'name'));

Nun meine Fragen:

  1. Ist es möglich, Werte mit einem Platzhalter (zB. "Wert*")? So etwas wie die folgenden (naiven) Ansatz:

    ...
    WHERE '{"Value%"}'::text[] <@ (json_val_arr(json, 'name'));
  2. Ist es möglich, numerische Werte mit Vergleichsoperatoren (zB. >= 10)? Wieder ein naiver und offensichtlich falsche Ansatz:

    ...
    WHERE '{10}'::int[] >= (json_val_arr(json, 'value'));

    Ich habe versucht, zu erstellen eine neue Funktion Rückkehr int[] aber das hat nicht funktioniert.

Erstellte ich eine SQL Fiddle zu verdeutlichen mein problem.

Oder wäre es besser einen anderen Ansatz wie die folgenden Werktag Abfragen:

SELECT *
FROM data,
   json_array_elements(json) jsondata
WHERE jsondata ->> 'name' LIKE 'Value%';

und

...
WHERE cast(jsondata ->> 'value' as integer) <= 10;

Jedoch, für diese Abfragen, ich war nicht in der Lage für die Erstellung eines index wurde tatsächlich abgeholt von den Abfragen.

Auch, würde ich mag, um alle implementieren diese in Postgresql 9.4 mit JSONB irgendwann, aber ich denke, für die oben genannten Fragen sollte dies kein Problem sein.

Vielen Dank!

InformationsquelleAutor lukas | 2014-07-31
Schreibe einen Kommentar