Athena:仅使用 JSON 个字段的子集
Athena: use only a subset of JSON fields
我有一个相当复杂的嵌套 JSON 日志。我想根据这些日志创建一个 Athena 外部 table,但只使用 table.
中的一些 JSON 字段
我有两个问题:
- 即使我不需要那里的大部分字段,我是否仍然需要创建一个包含嵌套结构的完整复杂 DDL?
- 假设我可以做到这一点,并且我将 JSON 日志以 Parquet 格式存储在 S3 中 - Athena 会只扫描我指定的那些 parts/fields 日志吗?或者它会以全价进行全面扫描吗? :-)
简化的 JSON 事件示例:
{
"name": "n1",
"f1": "v1",
"group1": {
"g1F1": "v1",
"g1F2": "v2",
"group11": {
"g11F1": "v1",
"g11F2": "v2"
},
"group12": {
"g12F1": "v1",
"g12F2": "v2"
}
},
"group2": {
"g2F1": "v1",
"g2F2": "v2",
...
},
...
}
假设我只对顶级字段 "name"、"f1" 和一些嵌套字段感兴趣,比如说 "group2" 的字段 "g2F1" 和 "g2F2"。
我可以这样做吗:
CREATE EXTERNAL TABLE mytable (
name string,
f1 string,
group2 struct<g2F1: string, g2F2: string>
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://<mybucket>'
?
当我尝试这种方法时 - DDL 运行没有错误,创建了 table,但是 'select * from mytable' returns 没有结果 ...
谢谢!!
更新:
Question/Problem1 的分辨率:
不知道为什么,但是一旦我再次将 gzip 日志重新上传到 S3 - table 创建和查询开始工作!
对于问题 2 - 请参阅下面 Tanveer 的回答。
更新 2:
对于那些也在考虑这个选项的人:我用大约 6G 的压缩数据创建了 Athena table - 一切都很好。但是,查询执行时间非常长。一个简单的查询,在几个字段上使用过滤器,大约需要 25-30 分钟......考虑到这只是一个 POC,使用 6G,我会有几百个 Ts - 这个选项对我来说不可行用例。当然,我没有使用 Parquet 格式 - 但由于我经常需要大部分列,我认为使用 Parquet 不会显着提高我的查询性能。
下面的答案。
您的查询未 returning 数据的原因是 Athena 不喜欢 json 数据中的换行符。您的 table 定义是完美的,您不需要对整个数据创建 table 定义。这就是读取模式的好处。您的整个数据应该在同一行如下。那么您的 Athena 查询将 return 数据。不要灰心。 Glue ETL 可以读取带有换行符的 json 文件,因为 Glue ETL 在后台运行 Spark。因此,您可以使用 Glue ETL 将 json 文件转换为 parquet,然后在 parquet 数据之上创建 Athena table。
{"name": "n1","f1": "v1","group1": {"g1F1": "v1","g1F2": "v2","group11": {"g11F1": "v1","g11F2": "v2"},"group12": { "g12F1": "v1","g12F2": "v2"}},"group2": {"g2F1": "v1","g2F2" : "v2"}}
将数据转换为 parquet 后,您只需为查询中使用的列付费,而不是为整个 table 付费,如 here 所述。
我有一个相当复杂的嵌套 JSON 日志。我想根据这些日志创建一个 Athena 外部 table,但只使用 table.
中的一些 JSON 字段我有两个问题:
- 即使我不需要那里的大部分字段,我是否仍然需要创建一个包含嵌套结构的完整复杂 DDL?
- 假设我可以做到这一点,并且我将 JSON 日志以 Parquet 格式存储在 S3 中 - Athena 会只扫描我指定的那些 parts/fields 日志吗?或者它会以全价进行全面扫描吗? :-)
简化的 JSON 事件示例:
{
"name": "n1",
"f1": "v1",
"group1": {
"g1F1": "v1",
"g1F2": "v2",
"group11": {
"g11F1": "v1",
"g11F2": "v2"
},
"group12": {
"g12F1": "v1",
"g12F2": "v2"
}
},
"group2": {
"g2F1": "v1",
"g2F2": "v2",
...
},
...
}
假设我只对顶级字段 "name"、"f1" 和一些嵌套字段感兴趣,比如说 "group2" 的字段 "g2F1" 和 "g2F2"。 我可以这样做吗:
CREATE EXTERNAL TABLE mytable (
name string,
f1 string,
group2 struct<g2F1: string, g2F2: string>
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://<mybucket>'
?
当我尝试这种方法时 - DDL 运行没有错误,创建了 table,但是 'select * from mytable' returns 没有结果 ...
谢谢!!
更新:
Question/Problem1 的分辨率: 不知道为什么,但是一旦我再次将 gzip 日志重新上传到 S3 - table 创建和查询开始工作!
对于问题 2 - 请参阅下面 Tanveer 的回答。
更新 2:
对于那些也在考虑这个选项的人:我用大约 6G 的压缩数据创建了 Athena table - 一切都很好。但是,查询执行时间非常长。一个简单的查询,在几个字段上使用过滤器,大约需要 25-30 分钟......考虑到这只是一个 POC,使用 6G,我会有几百个 Ts - 这个选项对我来说不可行用例。当然,我没有使用 Parquet 格式 - 但由于我经常需要大部分列,我认为使用 Parquet 不会显着提高我的查询性能。
下面的答案。
您的查询未 returning 数据的原因是 Athena 不喜欢 json 数据中的换行符。您的 table 定义是完美的,您不需要对整个数据创建 table 定义。这就是读取模式的好处。您的整个数据应该在同一行如下。那么您的 Athena 查询将 return 数据。不要灰心。 Glue ETL 可以读取带有换行符的 json 文件,因为 Glue ETL 在后台运行 Spark。因此,您可以使用 Glue ETL 将 json 文件转换为 parquet,然后在 parquet 数据之上创建 Athena table。
{"name": "n1","f1": "v1","group1": {"g1F1": "v1","g1F2": "v2","group11": {"g11F1": "v1","g11F2": "v2"},"group12": { "g12F1": "v1","g12F2": "v2"}},"group2": {"g2F1": "v1","g2F2" : "v2"}}
将数据转换为 parquet 后,您只需为查询中使用的列付费,而不是为整个 table 付费,如 here 所述。