2017-12-01 2 views
0

Ich habe eine JSON Spalte j wie:Extrahieren Sie alle JSON Schlüssel

{'a': 2, 'b': {'b1': 3, 'b2': 5}} 
{'c': 3, 'a': 5} 
{'d': 1, 'c': 7} 

Wie kann ich alle verschieden bekommen (Top-Level) Schlüsselnamen von Presto? I.e. Ich so etwas wie

select distinct foo(j) 

Um

['a', 'b', 'c', 'd'] 

(beachten Sie, dass in diesem Fall bin ich nicht zu sehr mit den verschachtelten Tasten) zurückkehren

Presto documentation keine Funktion haben, die explizit passt die Rechnung. Das einzige, was in der Nähe ist, ist die Erwähnung von JSONPath Syntax, aber auch das scheint ungenau zu sein. Mindestens eine der folgenden sollte etwas aber alle scheiterten in Presto für mich zurück:

select json_extract(j, '$.*') 
select json_extract(j, '$..*') 
select json_extract(j, '$[*]') 
select json_extract(j, '*') 
select json_extract(j, '..*') 
select json_extract(j, '$*.*') 

Außerdem vermute ich, dies wird wieder die Werte, nicht die Schlüssel, von j (das heißt [2, 3, 5, 3, 5, 1, 7]).

Antwort

1

Sie können

  1. Extrakt JSON Top-Level-Schlüssel mit map_keys(cast(json_column as map<varchar,json>))
  2. später "glätten" den wichtigsten Sammlungen mit CROSS JOIN UNNEST
  3. dann können Sie SELECT DISTINCT verschiedenen Top-Level-Schlüssel.

Beispiel setzen diese zusammen:

presto> SELECT DISTINCT m.key 
    -> FROM (VALUES JSON '{"a": 2, "b": {"b1": 3, "b2": 5}}', JSON '{"c": 3, "a": 5}') 
    ->  example_table(json_column) 
    -> CROSS JOIN UNNEST (map_keys(CAST(json_column AS map<varchar,json>))) AS m(key); 
key 
----- 
a 
b 
c 
(3 rows) 
+0

Eine zusätzliche Voraussetzung, daß, wenn Ihre Spalte als 'varchar' gespeichert ist wie' '{ "a": 2, "b": { "b1": 3 , "b2": 5}} ''wollen Sie mit' json_parse (json_column) ', _not_' cast (json_column als JSON) zu 'JSON' konvertieren' – MichaelChirico

+0

Gibt es eine Möglichkeit, dies ohne ein 'CROSS zu tun Mitmachen? Bei einem DB mit> 1 Milliarde Zeilen ist das sehr langsam. – MichaelChirico

+0

Mein Ansatz ist jetzt: Zoom in eine klein genug Teilmenge der Daten, wo ich ausführen kann (etwa 7 Millionen Zeilen, wo ich 36 eindeutige Schlüssel gefunden habe); Fügen Sie dann eine 'where not key in '(keys_found_from_narrow_query)' - Klausel zu einer breiteren Abfrage hinzu. 1) Ist dies tatsächlich ein besserer Ansatz, um eindeutige Schlüssel im gesamten Datensatz zu finden? 2) Gibt es einen besseren/weniger iterativen Weg, dies im Maßstab zu implementieren? – MichaelChirico

Verwandte Themen