OpenX jsonSerDe - Amazon Athena
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

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

OpenX jsonSerDe

就像 Hive JSON 一样SerDe,你可以使用 OpenX JSON 来处理 JSON 数据。这些数据还表示为用新行分隔的 JSON 编码文本的单行字符串。就像 Hive JSON 一样SerDe,OpenX JSONSerDe不允许重复密钥进入map要么struct密钥名称。

注意

这个SerDe期望每个 JSON 文档位于一行文本上,记录中的字段之间没有行终止字符。如果 JSON 文本的打印格式很漂亮,你可能会收到一条错误消息,比如HIVE_CURSOR_ERROR:行不是有效的 JSON 对象要么HIVE_CURSOR_ERROR:JsonParseException: 意想不到的 end-of-input: OBJECT 的预期关闭标记当你在创建表后尝试查询表时。有关更多信息,请参见JSON 数据文件在 OpenX 里SerDe上的文档GitHub。

可选属性

不像 Hive JSONSerDe,OpenX JSONSerDe还有以下可选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"(HIVE_CURSOR_ERROR:行不是有效的 JSON 对象 - JSONException:重复的键“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 兼容的名称

如果字段名称的 struct 中包含冒号,则可以使用 mapping 属性将该字段映射到与 Hive 兼容的名称。例如,假设您的列类型定义包含 my:struct:field:string,则可以通过在 WITH SERDEPROPERTIES 中加入以下条目来将定义映射到 my_struct_field:string

("mapping.my_struct_field" = "my:struct:field")

以下示例显示了对应的 CREATE TABLE 语句。

CREATE EXTERNAL TABLE colon_nested_field ( item struct<my_struct_field:string>) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ("mapping.my_struct_field" = "my:struct:field")

示例:广告数据

以下示例 DDL 语句使用 OpenX JSONSerDe根据 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' LOCATION 's3://myregion.elasticmapreduce/samples/hive-ads/tables/impressions';

示例:反序列化嵌套 JSON

你可以使用 JSONSerDes解析更复杂的 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/';