在Spark SQL中创建用户定义函数

在Spark SQL中创建用户定义函数,sql,apache-spark,Sql,Apache Spark,我是spark和spark sql的新手,我尝试使用spark sql查询一些数据 我需要从作为字符串给定的日期获取月份 我认为直接从sparkqsl查询month是不可能的,所以我考虑在scala中编写一个用户定义的函数 是否可以在sparkSQL中编写udf,如果可能,任何人都可以建议编写udf的最佳方法。如果您愿意使用语言集成查询,您可以这样做,至少在过滤方面 对于包含以下内容的数据文件dates.txt: one,2014-06-01 two,2014-07-01 three,2014-

我是spark和spark sql的新手,我尝试使用spark sql查询一些数据

我需要从作为字符串给定的日期获取月份

我认为直接从sparkqsl查询month是不可能的,所以我考虑在scala中编写一个用户定义的函数


是否可以在sparkSQL中编写udf,如果可能,任何人都可以建议编写udf的最佳方法。

如果您愿意使用语言集成查询,您可以这样做,至少在过滤方面

对于包含以下内容的数据文件dates.txt:

one,2014-06-01
two,2014-07-01
three,2014-08-01
four,2014-08-15
five,2014-09-15
您可以在您的UDF中添加任意数量的Scala date magic,但我会保持简单:

def myDateFilterdate:String=日期包含-08- 按如下所示进行设置-其中很多都是来自

val sqlContext=new org.apache.spark.sql.SQLContextsc 导入sqlContext_ //为您的记录提供案例课程 案例类Entryname:String,时间:String //读取并解析数据 val entries=sc.textFiledates.txt.map_u2;.split,.mape=>Entrye0,e1 您可以将UDF用作WHERE子句的一部分:

val augustEntries = entries.where('when)(myDateFilter).select('name, 'when)
并看到结果:

augustEntries.map(r => r(0)).collect().foreach(println)
注意我使用的where方法的版本,在文档中声明如下:

def其中[T1]arg1:Symboludf:T1⇒ 布尔:SchemaRDD 因此,UDF只能接受一个参数,但您可以组合多个.where调用以对多个列进行筛选

为Spark 1.2.0和真正的1.1.0进行编辑

Spark现在支持注册UDF,这样就可以从SQL查询UDF了,虽然它并没有真正的文档化

可以使用以下方式注册上述自定义项:

sqlContext.registerFunctionmyDateFilter,myDateFilter 如果表已注册

sqlContext.registerRDDAsTableentries,条目 可以使用

sqlContext.sqlSELECT*来自myDateFilterwhen所在的条目 有关更多详细信息,请参阅PySpark 1.5及更高版本中的。

,我们可以通过内置功能轻松实现这一点

以下是一个例子:

raw_data = 
[

("2016-02-27 23:59:59", "Gold", 97450.56),

("2016-02-28 23:00:00", "Silver", 7894.23),

("2016-02-29 22:59:58", "Titanium", 234589.66)]


Time_Material_revenue_df  = 
sqlContext.createDataFrame(raw_data, ["Sold_time", "Material", "Revenue"])

from pyspark.sql.functions import  *

Day_Material_reveneu_df = Time_Material_revenue_df.select(to_date("Sold_time").alias("Sold_day"), "Material", "Revenue")

在Spark 2.0中,您可以执行以下操作:

// define the UDF
def convert2Years(date: String) = date.substring(7, 11)
// register to session
sparkSession.udf.register("convert2Years", convert2Years(_: String))
val moviesDf = getMoviesDf // create dataframe usual way
moviesDf.createOrReplaceTempView("movies") // 'movies' is used in sql below
val years = sparkSession.sql("select convert2Years(releaseDate) from movies")

他们在网上说,Spark SQL目前仍然是阿尔法的东西。了解Spark SQL的人可能会在这里闲逛,但在这一点上,您可能有更好的机会学习有关它的新知识。UDAF用户定义聚合函数呢?我也一直在想这个问题,但到目前为止还没有发现支持它的任何证据。如果您愿意编写配置单元查询,则支持此功能,正如您在中所看到的,这是在中跟踪的-尚不支持。对于Spark 1.3+使用sqlContext.udf.registermyDateFilter和myDateFilter