Presto/Athena - 查询以发现 JSON 属性频率?
Posted
技术标签:
【中文标题】Presto/Athena - 查询以发现 JSON 属性频率?【英文标题】:Presto/Athena - query to discover JSON attribute frequencies? 【发布时间】:2017-09-04 22:06:34 【问题描述】:我定义了一个 Hive 表,其中单列包含 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/';
是否有 Presto/Athena 查询可以列出 JSON 中出现的所有字段名称及其频率(即属性在表中出现的总次数)?
【问题讨论】:
附言。表定义一团糟。 OpenCSVSerde?引用字符?转义字符? OpenCSVSerde 是 Athena 提供的选项之一。我现在正在使用org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
,但这并没有什么区别。对于 quoteChar 和 escapeChar 我只需要文件中不存在的字符。
【参考方案1】:
使用 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
【讨论】:
限于单级文档 附言。不需要子查询,可以在keys
别名的表达式上执行UNNEST
这很好用。使用正则表达式的另一个答案不能正确处理转义引号。【参考方案2】:
支持多级文档
忽略嵌套元素的键
select key
,count(*)
from t cross join
unnest (regexp_extract_all(json,'"([^"]+)"\s*:\s*("[^"]+"|[^,]+)',1)) u (key)
group by key
;
【讨论】:
运行良好,功能强大。在 json 上使用正则表达式感觉不对,尽管在这个问题中json
字段实际上是一个 varchar 类型(hive 字符串),所以正则表达式可能适合该数据类型。正如您所指出的,表定义是一团糟。
另外,这个答案交换了另一个答案中单级的限制,如果同一键出现在json中的多个级别,结果将不正确。以上是关于Presto/Athena - 查询以发现 JSON 属性频率?的主要内容,如果未能解决你的问题,请参考以下文章
用于在字符中获取字符串的正则表达式,第一个字符集在 Presto/Athena 中是可选的
如何在 Presto Athena 中将 varchar 转换为数组