Scala 使用Spark高阶函数时如何返回case类?
我试图使用Spark函数将数组的项从ClassA类型转换为ClassB,如下所示:Scala 使用Spark高阶函数时如何返回case类?,scala,apache-spark,Scala,Apache Spark,我试图使用Spark函数将数组的项从ClassA类型转换为ClassB,如下所示: 案例类ClassA(a:String,b:String,c:String) 案例类ClassB(a:字符串,b:字符串) val a1=A类(“a1”、“b1”、“c1”) val a2=A类(“a2”、“b2”、“c2”) val df=Seq( (序号(a1、a2)) ).toDF(“A类”) df.withColumn(“ClassB”,expr(“transform(ClassA,c->ClassB(c.
案例类ClassA(a:String,b:String,c:String)
案例类ClassB(a:字符串,b:字符串)
val a1=A类(“a1”、“b1”、“c1”)
val a2=A类(“a2”、“b2”、“c2”)
val df=Seq(
(序号(a1、a2))
).toDF(“A类”)
df.withColumn(“ClassB”,expr(“transform(ClassA,c->ClassB(c.a,c.b))”)).show(false)
尽管上述代码与消息一起失败:
org.apache.spark.sql.AnalysisException:未定义的函数:“ClassB”。
此函数既不是已注册的临时函数,也不是
在数据库“default”中注册的永久函数
实现此功能的唯一方法是通过struct
,如下所示:
df.withColumn("ClassB", expr("transform(ClassA, c -> struct(c.a as string, c.b as string))")).show(false)
// +----------------------------+--------------------+
// |ClassA |ClassB |
// +----------------------------+--------------------+
// |[[a1, b1, c1], [a2, b2, c2]]|[[a1, b1], [a2, b2]]|
// +----------------------------+--------------------+
所以问题是,当使用
transform
时,是否有任何方法返回case类而不是结构?transform表达式是关系型的,并且不知道case类ClassA
和ClassB
。
拥有AFAIK的唯一方法是注册一个UDF,这样就可以使用您的结构(或注入函数),但您还必须处理一个“行
”编码值,而不是ClassA(SparkSQL是关于编码:)),如下所示:
sparkSession.udf.register("toB", (a: Row) => ClassB(a.getAs[String]("a"), a.getAs[String]("b")))
df.withColumn("ClassB", expr("transform(ClassA, c -> toB(c))")).show(false)
旁注:将列命名为“ClassA”可能会让人困惑,因为transform读取的是列,而不是类型。我发现这部分是相关的,尽管没有解决case类问题。我认为您完全理解了这一点,我想知道是否有任何方法可以使用/编写一个泛型函数来处理上面为自定义类型(case类)实现的映射