【问题标题】:Parse json arrays using HIVE使用 HIVE 解析 json 数组
【发布时间】:2014-06-27 08:36:46
【问题描述】:

我有许多 json 数组存储在一个表 (jt) 中,如下所示:

[{"ts":1403781896,"id":14,"log":"show"},{"ts":1403781896,"id":14,"log":"start"}]
[{"ts":1403781911,"id":14,"log":"press"},{"ts":1403781911,"id":14,"log":"press"}]

每个数组都是一条记录。

我想解析这个表以获得一个包含 3 个字段的新表(日志):ts、id、log。 我尝试使用 get_json_object 方法,但似乎该方法与 json 数组不兼容,因为我只获取空值。

这是我测试过的代码:

CREATE TABLE logs AS 
SELECT get_json_object(jt.value, '$.ts') AS ts, 
get_json_object(jt.value, '$.id') AS id,
get_json_object(jt.value, '$.log') AS log
FROM jt;

我尝试使用其他功能,但它们看起来非常复杂。 谢谢! :)

更新! 我通过执行正则表达式解决了我的问题:

CREATE TABLE jt_reg AS
select regexp_replace(regexp_replace(value,'\\}\\,\\{','\\}\\\n\\{'),'\\[|\\]','') as valuereg  from jt;


CREATE TABLE logs AS 
SELECT get_json_object(jt_reg.valuereg, '$.ts') AS ts, 
get_json_object(jt_reg.valuereg, '$.id') AS id,
get_json_object(jt_reg.valuereg, '$.log') AS log
FROM ams_json_reg;

【问题讨论】:

    标签: arrays json hive


    【解决方案1】:

    我刚刚遇到了这个问题,将 JSON 数组作为字符串存储在 hive 表中。

    该解决方案有点笨拙和丑陋,但它可以工作并且不需要 serdes 或外部 UDF

    SELECT 
           get_json_object(single_json_table.single_json, '$.ts') AS ts,
           get_json_object(single_json_table.single_json, '$.id') AS id,
           get_json_object(single_json_table.single_json, '$.log') AS log
    FROM ( SELECT explode (
      split(regexp_replace(substr(json_array_col, 2, length(json_array_col)-2),
                '"}","', '"}",,,,"'), ',,,,')
          ) FROM src_table) single_json_table;
    

    为了便于阅读,我把这些行分开了。 我正在使用 substr() 去除第一个和最后一个字符,删除 [ 和 ] 。然后我使用 regex_replace 来匹配 json 数组中记录之间的分隔符,并将分隔符添加或更改为唯一的东西,然后可以轻松地使用 split() 将字符串转换为 json 对象的配置单元数组,然后可以如前一个解决方案中所述,与 explode() 一起使用。

    注意,此处使用的分隔符正则表达式 ( "}"," ) 不适用于原始数据集...正则表达式必须是 ( "},\{" ),然后替换需要是 "},,,,{" 例如..

      split(regexp_replace(substr(json_array_col, 2, length(json_array_col)-2),
                '"},\\{"', '"},,,,{"'), ',,,,')
    

    【讨论】:

    • 这很好!有没有其他方法可以做到这一点?你能解释一下使用的第一个正则表达式吗?
    【解决方案2】:

    因为get_json_object不支持json数组字符串,所以可以concat到一个json对象,像这样:

    SELECT 
        get_json_object(concat(concat('{"root":', jt.value), '}'), '$.root')
    FROM jt;
    

    【讨论】:

    • 结果是类型 String,至少在 Hive 1.1 上(这是旧的......)。
    • 结果对我来说也是字符串类型
    【解决方案3】:

    使用explode()函数

     hive (default)> CREATE TABLE logs AS
                      >   SELECT get_json_object(single_json_table.single_json, '$.ts') AS ts,
                      >   get_json_object(single_json_table.single_json, '$.id') AS id,
                      >   get_json_object(single_json_table.single_json, '$.log') AS log
                      >   FROM
                      >     (SELECT explode(json_array_col) as single_json FROM jt) single_json_table ;
    
    Automatically selecting local only mode for query
    Total MapReduce jobs = 3
    Launching Job 1 out of 3
    Number of reduce tasks is set to 0 since there's no reduce operator
    
    hive (default)> select * from logs;
    OK
    ts      id      log
    1403781896      14      show
    1403781896      14      start
    1403781911      14      press
    1403781911      14      press
    Time taken: 0.118 seconds, Fetched: 4 row(s)
    hive (default)>
    

    其中 json_array_col 是 jt 中的列,其中包含您的 json 数组。

    hive (default)> select json_array_col from jt;
    json_array_col
    ["{"ts":1403781896,"id":14,"log":"show"}","{"ts":1403781896,"id":14,"log":"start"}"]
    ["{"ts":1403781911,"id":14,"log":"press"}","{"ts":1403781911,"id":14,"log":"press"}"]
    

    【讨论】:

    • 感谢您的回复!它对我不起作用。我收到此错误:您的查询有以下错误:编译语句时出错:FAILED:UDFArgumentException explode() 将数组或映射作为参数。而不是“json_array_col”我放了“价值”。
    • value 的数据类型是什么。你可以粘贴以下内容:desc jt;
    • col_name:value,"data_type":"string"
    • 正如你在问题中提到的那样,你正在存储 json 数组,我用 explode() 给出了解决方案,explode() 将 Arrays/Map 作为 arg,这就是它的错误
    • 如果您的值类型是字符串,那么您必须编写 UDF 将逗号分隔的 json 字符串转换为数组并使用爆炸。最简单的方法是将数据存储到 hive 表中,使您的值数据类型为 Array
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 2013-03-21
    • 2013-08-27
    • 2016-06-19
    相关资源
    最近更新 更多