sql—如何在配置单元中用单个字段的混合结构/字符串值解析JSON?

b4lqfgs4  于 2021-06-25  发布在  Hive
关注(0)|答案(1)|浏览(204)

我得到了json数据,其结构类似于:

root
 |-- TX: struct (nullable = true)
 |    |-- ARGS: array (nullable = true)
 |    |    |-- element: string (containsNull = true)
 |    |-- COOKIE: array (nullable = true)
 |    |    |-- element: struct (containsNull = true)
 |    |    |    |-- name: string (nullable = true)
 |    |    |    |-- value: string (nullable = true)

数据的实际格式 ARGS 数组包含structs(与 COOKIE 数组),如下所示:

ARGS: {"name": "url", "value": "/index.html"}

但是,在文件的某些行中 ARGS 数组仅包含空值,这将强制配置单元将其解释为字符串:

ARGS: null

因为我知道 ARGS 是structs,我用的是 CREATE Hive中的声明如下:

CREATE EXTERNAL TABLE ${db}.${table}(
    tx struct<
        args:array<struct<name:string,value:string>>,
        cookie:array<struct<name:string,value:string>>
    >
) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION '${uri}';

因为这里的最终目标是横向化键值对数组,所以我使用这样的查询来测试:

SELECT array_pairs.name, array_pairs.value 
FROM ${db}.${table}
LATERAL VIEW EXPLODE(tx.args) EXPLODED_TABLE AS array_pairs;

如果我只查看色调中的前100行左右,这就可以了。但如果我尝试将其导出为csv或使用 WHERE 子句读取整个表,由于数据类型不匹配,配置单元弹出此错误:

errorMessage='java.lang.Error: Data is not JSONObject but java.lang.String with value alpha'

我知道最好的答案是有一个完美的数据源,但在这种情况下,数据就是它,我必须解析它。关于如何通过配置单元解析处理json中的空值,有什么提示吗?
编辑:10/24/2019 07:43
感谢@leftjoin,我意识到除了空值之外,还有一两个json对象 ARGS 字段由数组中的单个字符串填充:

ARGS: ["string value"]

既然如此,有没有办法让配置单元解析器忽略这些字符串,以便提取键值对?

sczxawaw

sczxawaw1#

尝试将serde属性设置为忽略格式错误的json:

ALTER TABLE json_table SET SERDEPROPERTIES ( "ignore.malformed.json" = "true");

相关问题