2017-08-24 102 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) //