2017-08-24 100 views
2

我有一个scala-2.11函数,它根据提供的类类型从Map创建一个case类。将案例类传递给Spark UDF

def createCaseClass[T: TypeTag, A](someMap: Map[String, A]): T = { 

    val rMirror = runtimeMirror(getClass.getClassLoader) 
    val myClass = typeOf[T].typeSymbol.asClass 
    val cMirror = rMirror.reflectClass(myClass) 

    // The primary constructor is the first one 
    val ctor = typeOf[T].decl(termNames.CONSTRUCTOR).asTerm.alternatives.head.asMethod 
    val argList = ctor.paramLists.flatten.map(param => someMap(param.name.toString)) 

    cMirror.reflectConstructor(ctor)(argList: _*).asInstanceOf[T] 
    } 

我想在火花数据框的上下文中使用这个作为UDF。但是,我不确定通过案例课程的最佳途径是什么。下面的方法似乎不起作用。

def myUDF[T: TypeTag] = udf { (inMap: Map[String, Long]) => 
    createCaseClass[T](inMap) 
    } 

我正在寻找像这 -

case class MyType(c1: String, c2: Long) 

val myUDF = udf{(MyType, inMap) => createCaseClass[MyType](inMap)} 

的思考和建议,以解决此表示赞赏。

回答

2

但是,我不知道什么是要通过案例类

这是不可能的使用情况下,类为用户自定义函数参数的最佳途径。 SQL StructTypes被映射为动态类型(缺少更好的单词)对象。

如果要对静态类型对象进行操作,请使用静态类型Dataset

1

从尝试和错误我得知存储在一个数据帧或数据集的任何数据结构使用org.apache.spark.sql.types

你可以看到:

df.schema.toString 

基本类型,如中等,双人,被存储,如:

StructField(fieldname,IntegerType,true),StructField(fieldname,DoubleType,true) 

复杂类型等情况下类被变换成嵌套类型的组合:

StructType(StructField(..),StructField(..),StructType(..)) 

样品的编号:

case class range(min:Double,max:Double) 
org.apache.spark.sql.Encoders.product[range].schema 

//Output: 
org.apache.spark.sql.types.StructType = StructType(StructField(min,DoubleType,false), StructField(max,DoubleType,false)) 

的UDF参数类型在此情况下是列,或SEQ [行]当您存储的情况下类的数组

基本调试TECHNIC是打印到字符串:

val myUdf = udf((r:Row) => r.schema.toString) 

然后,看到了发生:

df.take(1).foreach(println) //