无法在Spark中爆炸()Map [String,Struct]

时间:2019-08-09 18:43:12

标签: scala apache-spark apache-spark-sql

曾经为此苦苦挣扎了一段时间,但仍然无法确定。

我正在尝试flatMap(或将x.withColumn一起使用,因为它似乎更容易,因此我不会丢失列名),但是我总是遇到错误{{1} }。

我已经重新审视了一些类似的问题,但是由于它们的架构太简单,它们都没有引人注意。

我正在尝试使用flatMap的架构列如下...

explode()

我想要通过这样调用explode()来实现的目标...

UDTF expected 2 aliases but got 'name' instead

...是为了获得没有嵌套Map和Struct的行,所以我得到的行数与变体相同。

示例输入

StructField(CarMake,
  StructType(
    List(
      StructField(
        Models,
        MapType(
          StringType,
          StructType(
            List(
              StructField(Variant, StringType),
              StructField(GasOrPetrol, StringType)
            )
          )
        )
      )
    )
  ))

示例输出

carsDS
      .withColumn("modelsAndVariant", explode($"carmake.models"))

基本上将嵌套地图及其内部Strutt都保留在同一级别。

1 个答案:

答案 0 :(得分:1)

尝试一下:

case class Models(variant:String, gasOrPetrol:String)
case class CarMake(brand:String, models : Map[String, Models] )
case class MyRow(carMake:CarMake)

val df = List(
  MyRow(CarMake("volvo",Map(
    "850" -> Models("T5","petrol"),
    "V50" -> Models("T5","petrol")
  )))
).toDF()

df.printSchema()

df.show()

给予

root
 |-- carMake: struct (nullable = true)
 |    |-- brand: string (nullable = true)
 |    |-- models: map (nullable = true)
 |    |    |-- key: string
 |    |    |-- value: struct (valueContainsNull = true)
 |    |    |    |-- variant: string (nullable = true)
 |    |    |    |-- gasOrPetrol: string (nullable = true)


+--------------------+
|             carMake|
+--------------------+
|[volvo, [850 -> [...|
+--------------------+

现在爆炸,请注意withColumn不起作用,因为地图上的èxplode返回2列(keyvalue),因此您需要使用{{1 }}:

select

给予:

val cols: Array[Column] = df.columns.map(col)

df
  .select((cols:+explode($"carMake.models")):_*)
  .select((cols:+$"key".as("model"):+$"value.*"):_*)
  .show()