ich eine jsonb Spalte mit Beispielinhalt haben wie folgt:Wählen Sie die Anzahl der Einträge in einem bestimmten Schlüssel für eine PostgreSQL JSONB Spalte
{"kay1": val1, "myMap": {"UniqueKey1": "UniqueValue1", "UniqueKey2": "UniqueValue2", "UniqueKey3": "UniqueValue3", "UniqueKey4": "UniqueValue4"}, "key2": {"key3": {"key4": "val4"}, "val3": {"key5": "val5"}}
ich alle Zeilen finden möchten, wo Anzahl der Einträge in ‚myMap‘ größer sind als/gleich/kleiner als eine ganze Zahl - ich habe einige Millionen solcher Zeilen, daher wäre es hilfreich, wenn die Indizierung auch verwendet werden könnte!
Im obigen Beispiel gibt es 4 Einträge in 'myMap'. Für eine Abfrage wie "select * from myTable wo jsonb_key_length (myJsonbColumn -> 'myMap') = 4" sollte die obige Zeile zurückgegeben werden. [Angenommen, es gibt eine Funktion jsonb_key_length(), die die Länge des gegebenen json-Objekts zurückgibt]
Ich habe ähnliche Frage hier gefunden: Postgres json key count.
Aber es erfordert den Namen der Schlüssel, kann dies ohne Verwendung von Schlüsselnamen getan werden?
Lösung
Dank @jmelesky für seinen Vorschlag.
folgende Abfrage für mich gearbeitet:
SELECT id, count(elements)
FROM (SELECT id, jsonb_object_keys(column -> 'myMap') AS elements
FROM myTable GROUP BY id
) x
GROUP BY id
Einschließlich @ jmelesky Vorschlag
SELECT id, (SELECT count(*)
FROM (SELECT jsonb_object_keys(a->'myMap')
FROM test_json x where x.id = y.id
) z
) count
FROM test_json y group by id;
Gefunden eine andere, noch schnellere Lösung
SELECT id, ARRAY_LENGTH(ARRAY(SELECT jsonb_object_keys(column -> 'myMap')), 1) AS count
FROM myTable
Um Index verwenden:
Erstellen Sie eine Funktion:
CREATE OR REPLACE FUNCTION jsonb_object_keys_length(_j jsonb)
RETURNS INT LANGUAGE SQL IMMUTABLE AS
'SELECT ARRAY_LENGTH(ARRAY(SELECT jsonb_object_keys(column -> 'myMap')), 1)';
erstellen Index:
CREATE INDEX idx_myMapCount ON myTable (jsonb_object_keys_length(column -> 'myMap'));
Verwenden Sie die Funktion in Abfrage:
SELECT id, jsonb_object_keys_length(column -> 'myMap') AS count
FROM myTable
Bitte vorschlagen, wenn Es gibt einen besseren Weg um diese Abfrage zu modellieren. Vielen Dank!
Vielen Dank für Ihre Antwort. Aber diese Abfrage funktioniert nicht wie erwartet, da ich mehrere Zeilen habe, und ich möchte diese Anzahl für jede Zeile finden. Für zB: id | Spalte 1 | {"kay1": val1, "myMap": {"Eindeutiger Schlüssel1": "EindeutigerWert1", "Eindeutiger Schlüssel2": "EindeutigerWert2", "Eindeutiger Schlüssel3": "EindeutigerWert3", "EindeutigerSchlüssel4": "EindeutigerWert4"}, "Schlüssel2": { "key3": {"key4": "val4"}, "val3": {"key5": "val5"}} 2 | {"kay1": val1, "myMap": {"Eindeutiger Schlüssel21": "EindeutigerWert21", "Eindeutiger Schlüssel22": "EindeutigerWert22"}, "Schlüssel2": {"Schlüssel3": {"Schlüssel4": "Wert4"}, "Wert3 ": {" key5 ":" val5 "}} Ich möchte etwas wie: id | myMap_count 1 | 4 2 | 2 –
Etwas wie folgt aus: SELECT id, count (Elemente) FROM test_json tj, jsonb_each_text (tj.a -> myMap ') AS Elemente GROUP BY id Aber Abfragen anstelle der Verwendung 'von' –
Es ist relativ einfach. Etwas wie 'select id, (wählen Sie count (*) from (wählen Sie jsonb_object_keys (a -> 'myMap') aus test_json x wobei x.id = y.id) z) zählen aus test_json y group nach id; – jmelesky