如何在 Spark 中使用 Timestamp/Date 类型的参数创建 UDF

Posted

技术标签:

【中文标题】如何在 Spark 中使用 Timestamp/Date 类型的参数创建 UDF【英文标题】:How to create a UDF in Spark with a parameter of Timestamp/Date type 【发布时间】:2018-08-22 07:02:04 【问题描述】:

我正在尝试使用以下代码在 Spark 2.2 中创建 UDF:

spark.udf.register(
"DAYOFWEEK",
(timestamp: java.sql.Timestamp) => 
  new Timestamp()
  val cal = Calendar.getInstance()
  cal.setTime(timestamp)
  cal.get(Calendar.DAY_OF_WEEK)

稍后,当启动下一个 SQL 查询时:

SELECT DAYOFWEEK(now())

出现下一个异常:

cannot resolve 'UDF:DAYOFWEEK(current_timestamp())' due to data type mismatch: argument 1 requires bigint type, however, 'current_timestamp()' is of timestamp type.; line 1 pos 7;

我做错了什么?

【问题讨论】:

你有不同的UDF,它以bigint为参数吗? SELECT DAYOFWEEK(now()) 没有问题。你一定是在传递别的东西 【参考方案1】:

@Constantine 感谢您的建议。问题是已经注册了一个同名但使用日期作为参数的 UDF:

udf.register(
  "DAYOFWEEK",
  (date: Date) => 
    val cal = Calendar.getInstance()
    cal.setTime(date)
    cal.get(Calendar.DAY_OF_WEEK)
  
)

一旦会话只注册了一个 DAYOFWEEK UDF,它就会按预期工作

【讨论】:

【参考方案2】:
scala> sqlContext.udf.register(
     | "DAYOFWEEK",
     | (timestamp: java.sql.Timestamp) => 
     |   val cal = Calendar.getInstance()
     |   cal.setTime(timestamp)
     |   cal.get(Calendar.DAY_OF_WEEK)
     | );
res16: org.apache.spark.sql.UserDefinedFunction = UserDefinedFunction(<function1>,IntegerType,List(TimestampType))

scala> 

scala> val dd = sqlContext.sql("select DAYOFWEEK(now())")
dd: org.apache.spark.sql.DataFrame = [_c0: int]


scala> dd.show
+---+
|_c0|
+---+
|  4|
+---+

【讨论】:

以上是关于如何在 Spark 中使用 Timestamp/Date 类型的参数创建 UDF的主要内容,如果未能解决你的问题,请参考以下文章

如何在 AWS Glue 中使用 Spark 包?

如何在 Spark/Scala 中使用 countDistinct?

如何在数据块中使用 Spark sql 连接 Spark 数据框列

如何在 spark dataframes/spark sql 中使用模式读取 json

如何在 java 中使用 spark 2.0.0 预览版

如何使用 EMR 中的引导操作在 spark-conf 中添加 spark.executor.extraClassPath