簡體   English   中英

將案例類傳遞給Spark UDF

[英]Pass case class to Spark UDF

我有一個scala-2.11函數,該函數根據提供的類類型從Map創建一個案例類。

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]
  }

我試圖在Spark數據框架的上下文中將其用作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)}

提出了解決該問題的想法和建議。

但是,我不確定通過案例類的最佳方法是什么

案例類不能用作用戶定義函數的參數。 SQL StructTypes映射到動態類型(缺少更好的詞)的Row對象。

如果要對靜態類型的對象進行操作,請使用靜態類型的Dataset

通過反復試驗,我了解到,存儲在數據框或數據集中的任何數據結構都在使用org.apache.spark.sql.types

您可以看到:

df.schema.toString

基本類型(如Int,Double)的存儲方式如下:

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

諸如case類之類的復雜類型將轉換為嵌套類型的組合:

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參數類型為Row或Seq [Row]

基本的調試技術打印到字符串:

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

然后,看看發生了什么:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM