使用具有相同名称的嵌套子属性展平Spark JSON数据帧
作为Scala/Spark的noob,我有点卡住了,希望能得到任何帮助 我正在将JSON数据导入Spark数据帧。在这个过程中,我最终得到了一个数据帧,该数据帧在JSON输入中具有相同的嵌套结构 我的目标是使用Scala递归地展平整个数据帧(包括数组/字典中最内部的子属性)。 此外,可能存在具有相同名称的子属性。因此,也需要区分它们 此处显示了一个类似的解决方案(不同父级的子属性相同)—— 我希望实现的一个例子如下:使用具有相同名称的嵌套子属性展平Spark JSON数据帧,json,scala,apache-spark,dataframe,flatten,Json,Scala,Apache Spark,Dataframe,Flatten,作为Scala/Spark的noob,我有点卡住了,希望能得到任何帮助 我正在将JSON数据导入Spark数据帧。在这个过程中,我最终得到了一个数据帧,该数据帧在JSON输入中具有相同的嵌套结构 我的目标是使用Scala递归地展平整个数据帧(包括数组/字典中最内部的子属性)。 此外,可能存在具有相同名称的子属性。因此,也需要区分它们 此处显示了一个类似的解决方案(不同父级的子属性相同)—— 我希望实现的一个例子如下: { "id": "0001", "type": "donut"
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":
[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
}
相应的平坦输出火花DF结构为:
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters_batter_id_0": "1001",
"batters_batter_type_0": "Regular",
"batters_batter_id_1": "1002",
"batters_batter_type_1": "Chocolate",
"batters_batter_id_2": "1003",
"batters_batter_type_2": "Blueberry",
"batters_batter_id_3": "1004",
"batters_batter_type_3": "Devil's Food",
"topping_id_0": "5001",
"topping_type_0": "None",
"topping_id_1": "5002",
"topping_type_1": "Glazed",
"topping_id_2": "5005",
"topping_type_2": "Sugar",
"topping_id_3": "5007",
"topping_type_3": "Powdered Sugar",
"topping_id_4": "5006",
"topping_type_4": "Chocolate with Sprinkles",
"topping_id_5": "5003",
"topping_type_5": "Chocolate",
"topping_id_6": "5004",
"topping_type_6": "Maple"
}
之前没有与Scala和Spark进行过大量的合作,我不确定如何继续
最后,如果有人能够请帮助编写通用/非模式解决方案的代码,我将非常感激,因为我需要将其应用于许多不同的集合
非常感谢:)在我们的一个项目中,有一种可能性我们可以接近它
case class BattersTopics(id: String, type: String, ..., batters_batter_id_0: String, ..., topping_id_0: String)
val rows = dataSet.collect().toList
rows.map(bt => Map (
"id" -> bt.id,
"type" -> bt.type,
"batters" -> Map(
"batter" -> List(Map("id" -> bt.batters_batter_id_0, "type" ->
bt.batters_batter_type_0), ....) // same for the others id and types
"topping" -> List(Map("id"-> bt.topping_id_0, "type" -> bt.topping_type_0), ...) // same for the others id and type
)
))
df.map(row => BattersTopics(id = row.getAs[String]("id"), ...,
batters_batter_id_0 = row.getAs[String]("batters_batter_id_0 "), ...)
收集到一个列表,并从数据帧生成一个映射[String,Any]
case class BattersTopics(id: String, type: String, ..., batters_batter_id_0: String, ..., topping_id_0: String)
val rows = dataSet.collect().toList
rows.map(bt => Map (
"id" -> bt.id,
"type" -> bt.type,
"batters" -> Map(
"batter" -> List(Map("id" -> bt.batters_batter_id_0, "type" ->
bt.batters_batter_type_0), ....) // same for the others id and types
"topping" -> List(Map("id"-> bt.topping_id_0, "type" -> bt.topping_type_0), ...) // same for the others id and type
)
))
示例数据:包含所有不同类型的JSON元素(嵌套JSON映射、JSON数组、长字符串等) 这是json数据中具有
arraytype
和structtype
(映射)值的示例数据
我们可以为每种类型使用写前两个开关条件,并在未点亮的情况下重复此过程。它将变平为所需的Dataframe
这里是Spark Java API解决方案。Hi@dumitru,首先,感谢您的帮助:)据我所见,您已经生成了现有模式到输出模式的映射。但是,我的JSON文件可能有一些额外的字典元素,这些元素可能是我目前考虑的(动态生成的)。因此,需要在未知模式上递归展平的代码。然而,需要考虑儿童吸引力。也有相同的名字。