我试图查询具有复杂类型的spark sql数据帧,其中该函数本身应该能够创建和表达式以生成嵌套复杂数据类型的列数据帧。 说
case class SubRecord(x: Int)
case class ArrayElement(foo: String, bar: Int, vals: Array[Double])
case class Record(
an_array: Array[Int], a_map: Map[String, String],
a_struct: SubRecord, an_array_of_structs: Array[ArrayElement])
val df = sc.parallelize(Seq(
Record(Array(1, 2, 3), Map("foo" -> "bar"), SubRecord(1),
Array(
ArrayElement("foo", 1, Array(1.0, 2.0)),
ArrayElement("bar", 2, Array(3.0, 4.0)))),
Record(Array(4, 5, 6), Map("foz" -> "baz"), SubRecord(2),
Array(ArrayElement("foz", 3, Array(5.0, 6.0)),
ArrayElement("baz", 4, Array(7.0, 8.0))))
)).toDF
引自Querying Spark SQL DataFrame with complex types
用于提取地图类型查询的可以是
df.select($"a_map.foo").show
现在,如果我有
case class Record(
an_array: Array[Int], a_map_new: Map[String, Array[ArrayElement]],
a_struct: SubRecord, an_array_of_structs: Array[ArrayElement])
而不是Map [String,String],如何创建一个在数组的情况下获取名称或索引的udf,并为复杂数据类型中的嵌套元素生成结果。
假设现在我想查询vals[0] contained in a_map_new
。
答案 0 :(得分:1)
在这种情况下,如果您有明确定义的记录类型,我建议使用强类型Dataset
:
val result = df.as[Record].map(_.a_map_new.mapValues(_.headOption))
result.printSchema
// root
// |-- value: map (nullable = true)
// | |-- key: string
// | |-- value: struct (valueContainsNull = true)
// | | |-- foo: string (nullable = true)
// | | |-- bar: integer (nullable = false)
// | | |-- vals: array (nullable = true)
// | | | |-- element: double (containsNull = false)
udf
障碍是它的不对称性:
Row
。任何返回struct的通用解决方案都知道如何map
到外部类型。我想你可以设计这样的东西(伪代码)
def f(mapper: Row => T) = udf((map: Map[U, Row]) => map.mapValues(mapper(_)))