JSON SerDe 库 - Amazon Athena
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

JSON SerDe 库

在 Athena 中,您可以使用两个 SerDe 库来反序列化 JSON 数据。反序列化会转换 JSON 数据,以便它可以被序列化(写出)为不同的格式,如 Parquet 或 ORC。

SerDe 名称

Hive-JsonSerDe

Openx-JsonSerDe

库名称

使用以下值之一:

org.apache.hive.hcatalog.data.JsonSerDe

org.openx.data.jsonserde.JsonSerDe

Hive JSONSerDe

Hive JSON SerDe 通常用于处理 JSON 数据,如事件。这些事件表示为由换行符分隔的 JSON 编码文本块。Hive JSON SerDe 不允许 mapstruct 键名称中出现重复的键。

以下示例 DDL 语句使用 Hive JSON SerDe 基于示例在线广告数据创建表。在 LOCATION 子句中,替换 myregion 中的 s3://myregion.elasticmapreduce/samples/hive-ads/tables/impressions,带您在其中运行 Athena 的区域标识符(例如,s3://us-west-2.elasticmapreduce/samples/hive-ads/tables/impressions)。

CREATE EXTERNAL TABLE impressions ( requestbegintime string, adid string, impressionid string, referrer string, useragent string, usercookie string, ip string, number string, processid string, browsercookie string, requestendtime string, timers struct < modellookup:string, requesttime:string >, threadid string, hostname string, sessionid string ) PARTITIONED BY (dt string) ROW FORMAT serde 'org.apache.hive.hcatalog.data.JsonSerDe' with serdeproperties ( 'paths'='requestbegintime, adid, impressionid, referrer, useragent, usercookie, ip' ) LOCATION 's3://myregion.elasticmapreduce/samples/hive-ads/tables/impressions';

创建表后,运行 MSCK REPAIR TABLE 以加载表并使其可从 Athena 进行查询:

MSCK REPAIR TABLE impressions

OpenX JSON - SerDe

除了定义表中的列的 paths 属性以外,OpenX JSON SerDe 的以下可选属性对于解决数据中的不一致性很有用。

ignore.malformed.json

可选。设置为 TRUE 时,可让您跳过格式错误的 JSON 语法。默认为 FALSE

dots.in.keys

可选。默认值为 FALSE。 设置为 TRUE 时,允许 SerDe 将键名称中的点替换为下划线。例如,如果 JSON 数据集包含名为 "a.b" 的键,您可以在 Athena 中使用此属性来定义列名 "a_b"。默认情况下(没有此 SerDe),Athena 不允许在列名中使用点。

case.insensitive

可选。默认值为 TRUE。 在设置为 TRUE 时,SerDe 将所有大写列转换为小写。

要在数据中使用区分大小写的键名,请使用 WITH SERDEPROPERTIES ("case.insensitive"= FALSE;)。 然后,对于每个并非全部小写的键,请使用以下语法提供从列名到属性名的映射:

ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ("case.insensitive" = "FALSE", "mapping.userid" = "userId")

如果您有两个键(例如 URLUrl),并且二者在小写时是相同的,则可能会发生与以下内容类似的错误:

HIVE_CURSOR_ERROR: Row is not a valid JSON Object - JSONException: Duplicate key "url"

要纠正此错误,请将 case.insensitive 属性设置为 FALSE,并将键映射到不同的名称,如以下示例所示:

ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ("case.insensitive" = "FALSE", "mapping.url1" = "URL", "mapping.url2" = "Url")
映射

可选。将列名映射到与列名不同的 JSON 键。当 JSON 数据包含作为mapping关键字的键时, 参数很有用。例如,如果您有名为 timestamp 的 JSON 键,请使用以下语法将该键映射到名为 ts 的列:

ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ("mapping.ts"= "timestamp")

与 Hive JSON SerDe 类似,OpenX JSON SerDe 不允许 mapstruct 键名称中出现重复的键。

以下示例 DDL 语句使用 OpenX JSON SerDe 基于 Hive JSON SerDe 的示例中所用的相同示例在线广告数据创建表。 在 LOCATION 子句中,替换 myregion 替换为运行 Athena 的区域标识符。

CREATE EXTERNAL TABLE impressions ( requestbegintime string, adid string, impressionId string, referrer string, useragent string, usercookie string, ip string, number string, processid string, browsercokie string, requestendtime string, timers struct< modellookup:string, requesttime:string>, threadid string, hostname string, sessionid string ) PARTITIONED BY (dt string) ROW FORMAT serde 'org.openx.data.jsonserde.JsonSerDe' with serdeproperties ( 'paths'='requestbegintime, adid, impressionid, referrer, useragent, usercookie, ip' ) LOCATION 's3://myregion.elasticmapreduce/samples/hive-ads/tables/impressions';

示例:反序列化嵌套 JSON

您可以使用 JSON SerDes 分析更复杂的 JSON 编码的数据。这要求使用 CREATE TABLE 语句,而这些语句使用 structarray 元素来表示嵌套结构。

以下示例根据具有嵌套结构的 JSON 数据创建 Athena 表。要在 Athena 中解析 JSON 编码的数据,请确保每个 JSON 文档都各占一行,并用换行符分隔。

此示例假定 JSON 编码的数据具有以下结构:

{ "DocId": "AWS", "User": { "Id": 1234, "Username": "bob1234", "Name": "Bob", "ShippingAddress": { "Address1": "123 Main St.", "Address2": null, "City": "Seattle", "State": "WA" }, "Orders": [ { "ItemId": 6789, "OrderDate": "11/11/2017" }, { "ItemId": 4352, "OrderDate": "12/12/2017" } ] } }

以下 CREATE TABLE 语句将 OpenX-JSONSerdestructarray 集合数据类型结合使用来建立对象组。每个 JSON 文档都在其自己的行上列出,并用换行符分隔。为了避免错误,所查询的数据不会在 struct 或映射键名称中包含重复的键。

CREATE external TABLE complex_json ( docid string, `user` struct< id:INT, username:string, name:string, shippingaddress:struct< address1:string, address2:string, city:string, state:string >, orders:array< struct< itemid:INT, orderdate:string > > > ) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' LOCATION 's3://mybucket/myjsondata/';

其他资源

有关在 Athena 中使用 JSON 和嵌套 JSON 的更多信息,请参阅以下资源: