如何为 Hive 创建架构以使用 SerDe 解析深度嵌套的 json(Azure Application Insights 输出)?

Posted

技术标签:

【中文标题】如何为 Hive 创建架构以使用 SerDe 解析深度嵌套的 json(Azure Application Insights 输出)?【英文标题】:How do I create a schema for Hive to parse deeply nested json (Azure Application Insights output) using SerDe? 【发布时间】:2016-02-06 03:50:04 【问题描述】:

我正在尝试为 hive 创建用于解析 json 的架构,但是,当 json 文档采用以下结构时,我无法创建架构:


    "context":         
        "custom": 
            "dimensions": [
                "action": "GetFilters"
            ,
            
                "userId": "12345678"
            ]
        
    

我在 Windows (8.1) 上为 Azure 的 HDInsights 使用 Hadoop 模拟器,并且正在使用 java (1.8.0_73)。我用 Maven 成功编译了 SerDe。我认为以下方法会起作用:

add jar ../lib/json-serde-1.1.9.9-Hive1.2-jar-with-dependencies.jar;

DROP TABLE events;
CREATE EXTERNAL TABLE events (
  context STRUCT<custom:STRUCT<dimensions:array<STRUCT<action:string>,STRUCT<userId:string>>>>
) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION '/json/event';

当我取出嵌套的 ARRAY> 时,架构解析正常,但使用它,我得到以下异常:

MismatchedTokenException(282!=9) 在 org.antlr.runtime.BaseRecognizer.recoverFromMismatchedToken(BaseRecog nizer.java:617) 在 org.antlr.runtime.BaseRecognizer.match(BaseRecognizer.java:115) 在 org.apache.hadoop.hive.ql.parse.HiveParser.columnNameColonType(HivePa rser.java:34909) 在 org.apache.hadoop.hive.ql.parse.HiveParser.columnNameColonTypeList(嗨 veParser.java:33113) 在 org.apache.hadoop.hive.ql.parse.HiveParser.structType(HiveParser.java :36331) 在 org.apache.hadoop.hive.ql.parse.HiveParser.type(HiveParser.java:35334 ) 在 org.apache.hadoop.hive.ql.parse.HiveParser.colType(HiveParser.java:35 054) 在 org.apache.hadoop.hive.ql.parse.HiveParser.columnNameColonType(HivePa rser.java:34914) 在 org.apache.hadoop.hive.ql.parse.HiveParser.columnNameColonTypeList(嗨 veParser.java:33085) 在 org.apache.hadoop.hive.ql.parse.HiveParser.structType(HiveParser.java :36331) 在 org.apache.hadoop.hive.ql.parse.HiveParser.type(HiveParser.java:35334 ) 在 org.apache.hadoop.hive.ql.parse.HiveParser.colType(HiveParser.java:35 054) 在 org.apache.hadoop.hive.ql.parse.HiveParser.columnNameType(HiveParser. 爪哇:34754) 在 org.apache.hadoop.hive.ql.parse.HiveParser.columnNameTypeList(HivePar ser.java:32951) 在 org.apache.hadoop.hive.ql.parse.HiveParser.createTableStatement(HiveP arser.java:4544) 在 org.apache.hadoop.hive.ql.parse.HiveParser.ddlStatement(HiveParser.ja 弗吉尼亚州:2144) 在 org.apache.hadoop.hive.ql.parse.HiveParser.execStatement(HiveParser.j 爱娃:1398) 在 org.apache.hadoop.hive.ql.parse.HiveParser.statement(HiveParser.java: 1036) 在 org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:19 9) 在 org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:16 6) 在 org.apache.hadoop.hive.ql.Driver.compile(Driver.java:409) 在 org.apache.hadoop.hive.ql.Driver.compile(Driver.java:323) 在 org.apache.hadoop.hive.ql.Driver.compileInternal(Driver.java:980) 在 org.apache.hadoop.hive.ql.Driver.runInternal(Driver.java:1045) 在 org.apache.hadoop.hive.ql.Driver.run(Driver.java:916) 在 org.apache.hadoop.hive.ql.Driver.run(Driver.java:906) 在 org.apache.hadoop.hive.cli.CliDriver.processLocalCmd(CliDriver.java:2 68) 在 org.apache.hadoop.hive.cli.CliDriver.processCmd(CliDriver.java:220) 在 org.apache.hadoop.hive.cli.CliDriver.processLine(CliDriver.java:423) 在 org.apache.hadoop.hive.cli.CliDriver.executeDriver(CliDriver.java:793 ) 在 org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:686) 在 org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:625) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl。 爪哇:57) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces sorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:606) 在 org.apache.hadoop.util.RunJar.main(RunJar.java:212) 失败:ParseException 行 2:69 丢失 > 在列规范中的“STRUCT”附近 阳离子 第 2:76 行不匹配的输入“

hive>

【问题讨论】:

【参考方案1】:

我最终通过删除 ARRAY STRUCT 中的嵌套 STRUCT 使其工作,但我必须使用 [#] 访问这些值。例如,以下构建架构:

DROP TABLE events;
CREATE EXTERNAL TABLE events (
  context STRUCT<custom:STRUCT<dimensions:ARRAY<STRUCT<action:string,userId:string>>>>
) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION '/json/event';

然后我可以像这样访问诸如 userId 之类的项目:

SELECT context.custom.dimensions.userId[1] FROM events;

它有效,但不像我希望的那样可读。

【讨论】:

【参考方案2】:

那个外部桌子对我来说看起来不错。也许尝试下载该 JSON serde 的另一个发行版。我在以下方面取得了成功: http://www.congiu.net/hive-json-serde/

我在使用http://www.congiu.net/hive-json-serde/1.3/cdh5/ 的 HDInsight 3.2 中取得了成功,但您可以尝试使用更新的 HDP 构建。

这里的文档: https://github.com/rcongiu/Hive-JSON-Serde

【讨论】:

【参考方案3】:

我使用一组地图通过 rcongiu 的 JSON SerDe 处理 App Insights 自定义维度。 这是使用带有链接 blob 存储帐户的 HDInsight 群集。

add jar wasb://<mycontainer>@<mystorage>.blob.core.windows.net/json-serde-1.3.7-jar-with-dependencies.jar;
DROP TABLE Logs;
CREATE EXTERNAL TABLE Logs (
  event array<struct<
    count:int, 
    name:string>
  >,
  context struct<
    custom:struct<
        dimensions:array<map<string, string>>
        >
  >
  )
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 'wasb://<mycontainer>@<mystorage>.blob.core.windows.net/events/';

SELECT 
    event[0].name as EventName,
    context.custom.dimensions[0]['action'] as Action, 
    context.custom.dimensions[1]['key'] as Key
FROM Logs
WHERE event[0].name = 'Click';

【讨论】:

以上是关于如何为 Hive 创建架构以使用 SerDe 解析深度嵌套的 json(Azure Application Insights 输出)?的主要内容,如果未能解决你的问题,请参考以下文章

在 Hive 中使用 Regex Serde 创建表返回错误

Hive with Regex SerDe 拆分行,每个单词成为一列

行格式 serde 是创建 Hive 表时要使用的强制参数吗

Row格式serde是创建Hive表时要使用的必需参数

使用 JSON-SERDE 将 JSON 数据摄取到 Hive

hive 存储,解析,处理json数据