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 JSON SerDe

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

以下示例 DDL 语句使用 Hive JSON SerDe 基于示例在线广告数据创建表。在 LOCATION 条款,更换 myregions3://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 定义表中列的属性,OpenXJSONSerde具有以下可选属性,可用于解决数据中的不一致性。

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 的更多信息,请参阅以下资源: