在配置单元中将JSON格式字符串转换为数组

在配置单元中将JSON格式字符串转换为数组,json,oracle,hadoop,hive,Json,Oracle,Hadoop,Hive,我有一个存储JSON格式字符串的数据库列。字符串本身包含类似数组的多元组元素。每个元素包含多个键值对。某些值也可能包含多个键值对,例如下面的“address”属性 [{"name":"abc", "address":{"street":"str1", "city":"c1"}, "phone":"1234567" }, {"name":"def", "address":{"street":"str2", "city":"c1"}, "phone":"7145895" }

我有一个存储JSON格式字符串的数据库列。字符串本身包含类似数组的多元组元素。每个元素包含多个键值对。某些值也可能包含多个键值对,例如下面的“address”属性

[{"name":"abc", 
  "address":{"street":"str1", "city":"c1"},
  "phone":"1234567"
 },
 {"name":"def", 
  "address":{"street":"str2", "city":"c1"},
  "phone":"7145895"
 }
]

我的最终目标是获取JSON字符串中每个字段的单个值。我可能会使用explode()来实现这一点,但是explode()需要向其中传递数组,而不是字符串。因此,我的第一个目标是将JSON字符串转换为数组。有人能告诉我怎么做吗?非常感谢。

您可以从以下内容开始:

select concat(‘{“name”’,data_json) from your_table q1 --re-construct your json
lateral view explode(split(json_data,’{“name”’)) json_splits as data_json --split json at each {"name" tag into array and then explode

注意:我的代码没有经过测试,因为我目前没有访问配置单元的权限。这肯定会给您一个良好的开端,或者您可以始终使用Hive SerDe for JSON
com.cloudera.Hive.SerDe.JSONSerDe

正如@ruben123所建议的,使用Hive SerDe for JSON,尤其是当您的JSON比较复杂时。有几种可用的JSONSerDe,例如
com.cloudera.hive.serde.JSONSerDe
org.openx.data.JSONSerDe.JSONSerDe

确保json格式正确,一行json对应一条记录。因此,您的json应该是:

{"name":"abc", "address":{"street":"str1", "city":"c1"}, "phone":"1234567"}
{"name":"def", "address":{"street":"str2", "city":"c1"}, "phone":"7145895"} 
创建配置单元表:

CREATE TABLE sample_json (
   name STRING,
   address STRUCT<
     street: STRING,
     city: STRING>,
   phone INT )
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION '/your/hdfs/directory';

注意:如果JSONSerDe尚未安装,则必须运行
addjar

,非常感谢您的支持reply@jlp他发布了他的专栏中只有一个有json字符串。因为SerDe本质上是一个序列化-反序列化框架,所以JsonSerDe只能应用于整个表,对吗?如果用户混合使用了数据Json和非Json管道,该怎么办?即使用户使用RegexSerde,Json部分仍然是字符串。在这种情况下,我们应该如何分解字符串json?
select name, address.street, address.city, phone from sample_json;

abc   str1  c1  1234567
def   str2  c1  7145895