从Spark-Scala UDF返回Seq [Row]

时间:2017-01-06 22:56:08

标签: scala apache-spark apache-spark-sql user-defined-functions

我使用Spark和Scala进行一些数据处理。我有XML数据映射到dataframe。我将一行作为参数传递给UDF并尝试将两个复杂类型对象作为列表提取。 Spark给了我以下错误:

  

线程中的异常" main" java.lang.UnsupportedOperationException:不支持类型为org.apache.spark.sql.Row的模式

def testUdf = udf((testInput: Row) => {
  val firstObject = testInput.getAs[Row]("Object1")
  val secondObject = testInput.getAs[Row]("Object2")
  val returnObject = Seq[firstObject,secondObject]

  returnObject
})
你能告诉我我做错了吗?感谢。

2 个答案:

答案 0 :(得分:2)

UDF无法返回Row个对象。返回类型必须是Data Types table中Scala列值类型中枚举的类型之一。

好消息是这里不需要UDF。如果Object1Object2 具有相同的架构(无论如何都不会起作用),您可以使用array函数:

import org.apache.spark.sql.functions._

df.select(array(col("Object1"), col("Object2"))

df.select(array(col("path.to.Object1"), col("path.to.Object2"))

如果Object1Object2不是顶级列。

答案 1 :(得分:0)

我想建议一种替代方法,如果object1和object2的架构不同并且您可以返回该行,则可以使用该方法。 基本上要返回row,您只需返回一个具有Row对象架构的case类,在这种情况下,它们是object1和object2,它们本身似乎是行

执行以下操作

case class Object1(<add the schema here>)

case class Object2(<add the schema here>)

case class Record(object1:Object1,object2:Object2)

现在在UDF中,您可以使用firstObject和secondObject来创建object1和object2

然后

val record = Record(object1,object2)

然后您可以返回record

在这种情况下,即使架构不相同或需要进行一些处理,您也可以返回行。

我知道这实际上与您的问题无关,但是这个问题似乎是一个正确的机会来介绍这个概念。