如何使用Spark Session在Spark2中重载UDF

时间:2018-03-21 12:13:08

标签: apache-spark apache-spark-sql spark-dataframe

如何使用Spark Session在Spark2中实现方法重载UDF。

scala> spark.udf.register("func",(a:String)=>a.length)   

scala> spark.udf.register("func",(a:Int)=>a*1000)

以下是我的名为'orc'的Hive表及其描述

scala> spark.sql("desc orc").collect.foreach(println)
[id,int,null]
[name,string,null]
[time_stamp,timestamp,null]

我的表中有两条记录

scala> spark.sql("select * from orc").collect.foreach(println)
[1,Pratap Chandra Dhan,null]
[2,Dyuti Ranjan Nayak,2016-01-01 00:00:00.0]

当我使用spark会话查询时,第二个函数生效,防止方法重载

scala> spark.sql("select func(id),func(name) from  orc").collect.foreach(println)
[1000,null]
[2000,null]

2 个答案:

答案 0 :(得分:0)

如果确实需要(请参阅评论),您可以定义func来处理多种类型的输入,如下所示并注册:

scala> val func = (a: Any) => {
     |       val i = a match {
     |       case s:String => s.length
     |       case d:Integer => d * 1000
     |       //case _ => 0
     |       }
     |       i
     |       }
func: Any => Int = <function1>

scala> spark.udf.register("func",func)

答案 1 :(得分:0)

当具有相同名称的函数的范围被定义为具有不同的范围 ,即在类或对象内时,

函数重载工作

在函数内定义函数时,

函数重载不起作用。最新定义接管,即覆盖最新定义

例如

我将两个函数func定义为不同类型的参数

scala> def func(a:String) = a.length
func: (a: String)Int

scala> def func(a: Int) = a*2
func: (a: Int)Int    

然后我尝试调用第一个定义

scala> func("sell")
<console>:13: error: type mismatch;
 found   : String("sell")
 required: Int
       func("sell")
            ^                                                                                                                                                                                                                                                                                                                      

如果我调用第二个定义(最新的定义),它可以正常工作

scala> func(3)
res1: Int = 6

我再次定义第一个定义,即最新的定义是第一个定义

scala> def func(a:String) = a.length
func: (a: String)Int

现在第一个函数调用

scala> func("sell")
res2: Int = 4

函数重载在普通REPL中不起作用。您必须输入:粘贴模式

scala> :paste
// Entering paste mode (ctrl-D to finish)

def func(a:String) = a.length
def func(a: Int) = a*2

// Exiting paste mode, now interpreting.

func: (a: String)Int <and> (a: Int)Int
func: (a: String)Int <and> (a: Int)Int

scala> func("sell")
res0: Int = 4

scala> func(3)
res1: Int = 6