2017-04-10 19 views
0

我已经定义了一个蜂巢表,其中一列包含JSON文本:Presto/Athena - 查询发现JSON属性频率?

CREATE EXTERNAL TABLE IF NOT EXISTS my.rawdata (
    json string 
) 
PARTITIONED BY (dt string) 
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.OpenCSVSerde' 
WITH SERDEPROPERTIES (
    'separatorChar' = '\n', 
    'quoteChar' = '\0', 
    'escapeChar' = '\r' 
) 
STORED AS TEXTFILE 
LOCATION 's3://mydata/'; 

是否有普雷斯托/雅典娜查询可以列出了JSON内发生的所有字段名和它们的频率(即总数该属性出现在表中)?

+0

P.S.的钥匙表格定义是一团糟。 OpenCSVSerde? quoteChar? escapeChar? –

回答

0

使用JSON函数解析JSON并将其转换为地图。然后提取他们的密钥和unnest。最后,使用正常的SQL聚集:

SELECT key, count(*) 
FROM (
    SELECT map_keys(cast(json_parse(json) AS map(varchar, json))) AS keys 
    FROM rawdata 
) 
CROSS JOIN UNNEST (keys) AS t (key) 
GROUP BY key 
+0

限于单级文档 –

+0

P.不需要子查询,UNNEST可以通过'keys'实现别名表达。 –

1
  • 支持多层次的文件
  • 忽略嵌套元素

select key 
     ,count(*) 
from  t cross join 
      unnest (regexp_extract_all(json,'"([^"]+)"\s*:\s*("[^"]+"|[^,{}]+)',1)) u (key) 
group by key 
; 
+0

工作良好,功能强大。感觉在json上使用正则表达式是错误的,尽管在这个问题中'json'字段实际上是一个varchar类型(hive字符串),所以正则表达式可能适合该数据类型。如你所指出的,表定义是一团糟。 – Davos

+0

另外,这个答案在另一个答案中交换了单层的限制,如果在json的多个层次中出现相同的键,结果将会不正确。 – Davos