我想将一组结构分解为列(由结构字段定义)。 E.g。
root
|-- arr: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- id: long (nullable = false)
| | |-- name: string (nullable = true)
应转换为
root
|-- id: long (nullable = true)
|-- name: string (nullable = true)
我可以用
实现这一目标df
.select(explode($"arr").as("tmp"))
.select($"tmp.*")
如何在单个选择语句中执行此操作?
我认为这可行,不幸的是它没有:
df.select(explode($"arr")(".*"))
线程中的异常" main" org.apache.spark.sql.AnalysisException:没有 这样的struct field。* in col;
答案 0 :(得分:0)
单步解决方案仅适用于MapType
列:
val df = Seq(Tuple1(Map((1L, "bar"), (2L, "foo")))).toDF
df.select(explode($"_1") as Seq("foo", "bar")).show
+---+---+
|foo|bar|
+---+---+
| 1|bar|
| 2|foo|
+---+---+
使用数组,您可以使用flatMap
:
val df = Seq(Tuple1(Array((1L, "bar"), (2L, "foo")))).toDF
df.as[Seq[(Long, String)]].flatMap(identity)
单个SELECT
语句可以用SQL编写:
df.createOrReplaceTempView("df")
spark.sql("SELECT x._1, x._2 FROM df LATERAL VIEW explode(_1) t AS x")