Json 使用嵌套数组原始火花sql分解数组

Json 使用嵌套数组原始火花sql分解数组,json,hive,apache-spark-sql,Json,Hive,Apache Spark Sql,我有以下json结构,它作为字符串存储在我的配置单元表列中 [ {"outer_id": 123000, "outer_field_1": blah, "inner_list": [{"inner_id": 456}, {"inner_id": 789}]}, {"outer_id": 123001, "outer_field_1": blahbla

我有以下json结构,它作为字符串存储在我的配置单元表列中

[  
{"outer_id": 123000, "outer_field_1": blah, "inner_list": [{"inner_id": 456}, {"inner_id": 789}]},  
{"outer_id": 123001, "outer_field_1": blahblah, "inner_list": [{"inner_id": 456}, {"inner_id": 789}]},  
{"outer_id": 123002, "outer_field_1": blahblahblah,  "inner_list": [{"inner_id": 456}, {"inner_id": 789}]},  
]
现在,我想将它解析为一个表,表中的外部数组元素作为每一行。每个json对象的字段被解析为每个列,同时仍将内部列表保留为字符串:

| outer_id | outer_field_1 | inner_list | | | |----------|---------------|-------------|---|---| | 123000 | blah | struct | | | | 123001 | blahblah | struct | | | | 123002 | blahblahblah | struct | | |
假设我理解正确,您有以下几点:

输入 期望输出: 首先,需要将字符串解析为定义模式的模式:

schema = ArrayType(
   StructType([StructField('outer_id', IntegerType()), 
               StructField('outer_field_1', StringType()), 
               StructField('inner_list', StringType())])
)
请注意,这是一个简单的版本,其中internal_List只是作为字符串

在数据帧上应用该架构:

df = df.select(from_json('outer_list', schema).alias('test'))
现在您有了一个带有数组的列:

+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|test                                                                                                                                                                       |
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|[[123000, blah, [{"inner_id":456},{"inner_id":789}]], [123001, blahblah, [{"inner_id":456},{"inner_id":789}]], [123002, blahblahblah, [{"inner_id":456},{"inner_id":789}]]]|
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
您现在可以对此进行分解:

df.select(explode('test').alias('exploded')).select('exploded.*')
因此:

+--------+-------------+-----------------------------------+
|outer_id|outer_field_1|inner_list                         |
+--------+-------------+-----------------------------------+
|123000  |blah         |[{"inner_id":456},{"inner_id":789}]|
|123001  |blahblah     |[{"inner_id":456},{"inner_id":789}]|
|123002  |blahblahblah |[{"inner_id":456},{"inner_id":789}]|
+--------+-------------+-----------------------------------+
现在,在解析外部列表时,您可以从一开始就对内部列表执行相同的操作。但是你应该先自己试试,你这里有你需要的一切

别忘了导入:

from pyspark.sql.functions import *
from pyspark.sql.types import *
SQL版本(如果输入为表json_test):
你可以再编辑一下你想要的输出吗。我不确定你期望的是什么。@Matt为Clarity编辑过所以内部列表不重要?是的,但现在我只想分解外部列表,整个需求有点复杂。。。让我编辑这个问题,使内部列表仍然是一个字符串,因为我没有完全阅读它,所以基本上你有这样一个表:{a:1,外部列表:[{outer\u id:123000,outer\u field\u 1:blah,inner\u list:[{inner\u id:456},{inner\u id:789},{outer\u id:123001,outer\u field\u 1:blahblah,inner\u list:[{inner\u id:456,{789},{outer_id:123002,outer_field_1:blahblahblah,inner_list:[{inner_id:456},{inner_id:789}]},]}您好,Matt,谢谢您的回答。如果我使用pyspark或scala,这将很容易,但我想在原始SQL中执行此操作,这意味着您向CLIHi@Matt发出的SELECT*FROM xxx类查询的输入是json字符串,因此转换也需要使用纯SQL。这是纯SQL。请参见我答案的结尾我使用sql解析json我不确定你需要什么moreHi@matt,上面的sql对我不起作用。我在spark sql查询中写了以下内容,并抛出了错误:``从json中选择[{\outer\u id\:123000,\outer\u field\u 1\:\blah\,\inner\u list\:[{\inner\u id\:456},{\inner\u id\:789}],数组“``似乎是from_json的语法错误:==SQL==array--^^^;第1行pos 7我想我们需要添加一个根键,我们很好,请参阅:
df.select(explode('test').alias('exploded')).select('exploded.*')
+--------+-------------+-----------------------------------+
|outer_id|outer_field_1|inner_list                         |
+--------+-------------+-----------------------------------+
|123000  |blah         |[{"inner_id":456},{"inner_id":789}]|
|123001  |blahblah     |[{"inner_id":456},{"inner_id":789}]|
|123002  |blahblahblah |[{"inner_id":456},{"inner_id":789}]|
+--------+-------------+-----------------------------------+
from pyspark.sql.functions import *
from pyspark.sql.types import *
select exploded.* from 
   (select explode(
             from_json(
               outer_list, 
    "array<struct<outer_id:int,outer_field_1:string,inner_list:string>>"
       )
    ) as exploded from json_test
)