Scala Spark Dataframe:用StructType值中的非齐次数据类型表示MapType的架构
我试图创建一个StructType模式来传递给from_json API,以便解析存储为json字符串的列。JSON数据包含一个映射,该映射具有字符串键和struct类型的值,但每个struct的模式取决于键 考虑这个JSON示例,“数据”列是一个带有值Scala Spark Dataframe:用StructType值中的非齐次数据类型表示MapType的架构,scala,apache-spark,Scala,Apache Spark,我试图创建一个StructType模式来传递给from_json API,以便解析存储为json字符串的列。JSON数据包含一个映射,该映射具有字符串键和struct类型的值,但每个struct的模式取决于键 考虑这个JSON示例,“数据”列是一个带有值name和address的映射,每个值的模式都不同: { "data": { "name": { "first": "john" },
name
和address
的映射,每个值的模式都不同:
{
"data": {
"name": {
"first": "john"
},
"address": {
"street": "wall",
"zip": 10000
}
}
}
对于键“name”,结构值有一个成员字段“first”。对于键“address”,结构值有两个成员字段“street”和“zip”
“数据”列能否在Spark数据框中表示为MapType[StringType,StructType]
MapType
共享一个StructType架构示例,其中StructType是非同构的<强>编辑:要添加一个具有map(string,Stutt)的数据的另一个示例,其中结构在整个映射的值中不具有相同的模式,请考虑以下内容:
case类地址(street:String,zip:Int)
案例类名称(第一个:字符串)
案例类员工(id:String,角色:String)
val map=map(
“地址”->地址(“墙”,10000),
“姓名”->姓名(“约翰”),
“职业”->员工(“12345”,“软件工程师”)
)
正如您所看到的,映射的值在模式上有所不同-Address、Name和Employee都是不同的case类,它们的成员字段也不同
您可以想象这种数据来自一个JSON文件,其中一个映射允许跨键具有任意类型的值,并且对所有相同类型的值没有限制。在我的例子中,我的值都是结构,但每个结构的模式取决于映射键。您可以读取JSON列并动态解析模式:
import org.apache.spark.sql.functions.{col,from_json}
导入spark.implicits_
val df=sc.并行化(序号(
(“{”数据“{”姓名“{”第一名“{”约翰“}”,地址“{”街道“{”墙“,”邮编“:10000}”,职业“{”id“:”12345“,”角色“:”软件工程师“}}}”),
(“{”数据“:{”姓名“:{”第一名“:”约翰“}”,地址“{”街道“:”墙“,”邮政编码“:”10000}}}”),
)).toDF(“my_json_列”)
val rows=df.select(“my_json_column”).as[String]
val schema=spark.read.json(rows.schema)
//将字符串转换为Struct
val newDF=df.withColumn(“obj”,来自于_json(col(“my_json_column”),schema))
newDF.printSchema
//根
//|--my_json_列:string(nullable=true)
//|--obj:struct(nullable=true)
//| |--data:struct(nullable=true)
//| | |--地址:struct(nullable=true)
//| | |--street:string(nullable=true)
//| | | |--zip:long(nullable=true)
//| | |--名称:struct(nullable=true)
//| | | |--first:string(nullable=true)
//| | |--占用:struct(nullable=true)
//| | | |--id:string(nullable=true)
//| | | |--角色:字符串(nullable=true)
newDF.select(“obj.data”、“obj.data.occulation.id”).show(false)
输出
+---------------------------------------------------+-----+
|data |id |
+---------------------------------------------------+-----+
|{{wall, 10000}, {john}, {12345, Software Engineer}}|12345|
|{{wall, 10000}, {john}, null} |null |
+---------------------------------------------------+-----+
你能分享更多的数据样本吗?我想弄清楚你的数据是什么样的非同质数据is@Kafels我添加了更多的数据,如果没有帮助,请告诉我答案,请检查它,如果Scala模式出现任何错误,请为我修复它,因为这是我第一次在Scala中编写代码