选项 1 - 在 EMR 上使用 json_extract 内置函数 Presto
我假设您已经使用 EMR 启动了 Presto。
最简单的方法是使用 Presto 默认自带的 json_extract 函数。
假设你在 s3 上有一个这样的 json 文件:
{"a": "a_value1", "b": { "bb": "bb_value1" }, "c": "c_value1"}
{"a": "a_value2", "b": { "bb": "bb_value2" }, "c": "c_value2"}
{"a": "a_value3", "b": { "bb": "bb_value3" }, "c": "c_value3"}
...
...
每一行代表一个 json 树对象。
因此,您可以简单地预先定义一个包含一个字符串类型字段的表,然后使用json_extract轻松查询该表。
SELECT json_extract(json_field, '$.b.bb') as extract
FROM my_table
结果会是这样的:
| extract |
|-----------------|
| bb_value1 |
| bb_value2 |
| bb_value3 |
这可能是使用 presto 读取 json 文件的一种快速简便的方法,但不幸的是,这不适用于大型 json 文件。
json_extract 上的一些 presto 文档:https://prestodb.github.io/docs/current/functions/json.html#json_extract
选项 2 - 在 EMR 上使用特定 Serde 用于 json 文件的 Presto
您还可以通过添加自定义插件或 SerDe 库,在 emr 集群的引导阶段自定义您的 presto。
因此,您只需选择一个可用的 JSON SerDe 库(例如 org.openx.data.jsonserde.JsonSerDe)并按照他们的指南定义与 Json 文件结构匹配的表。
您将能够以与 json_extract 类似的方式(使用点分符号)访问 json 文件的字段,并且它应该更快并且在大文件上可以很好地扩展。不幸的是,使用这种方法你有两个主要问题:
1) 为复杂的文件定义一个表就像在地狱。
2) 您可能有内部 java cast 异常,因为 json 中的数据无法被 SerDe 库轻松转换。
选项 3 - Athena 内置 JSON Serde
https://docs.aws.amazon.com/athena/latest/ug/json.html
似乎你有一些 Json SerDe 也内置在 Athena 中,我个人从未尝试过这些,但它们由 AWS 管理,所以应该更容易设置一切。