![](/img/trans.png)
[英]Creating User Defined (not temporary) Function in Spark-SQL for Azure Databricks
[英]Creating User Defined Function in Spark-SQL
我是 spark 和 spark sql 的新手,我试图使用 spark SQL 查询一些数据。
我需要从以字符串形式给出的日期中获取月份。
我认为不可能直接从 sparkqsl 查询月份,所以我想在 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 日期魔法,但我会保持简单:
def myDateFilter(date: String) = date contains "-08-"
将其全部设置如下 - 其中很多来自编程指南。
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
import sqlContext._
// case class for your records
case class Entry(name: String, when: String)
// read and parse the data
val entries = sc.textFile("dates.txt").map(_.split(",")).map(e => Entry(e(0),e(1)))
您可以使用 UDF 作为 WHERE 子句的一部分:
val augustEntries = entries.where('when)(myDateFilter).select('name, 'when)
并查看结果:
augustEntries.map(r => r(0)).collect().foreach(println)
请注意我使用的where
方法的版本,在文档中声明如下:
def where[T1](arg1: Symbol)(udf: (T1) ⇒ Boolean): SchemaRDD
因此,UDF 只能采用一个参数,但您可以组合多个.where()
调用来过滤多列。
针对 Spark 1.2.0 进行编辑(实际上也是 1.1.0)
虽然它没有真正记录在案,但 Spark 现在支持注册 UDF,以便可以从 SQL 查询。
可以使用以下方法注册上述 UDF:
sqlContext.registerFunction("myDateFilter", myDateFilter)
如果该表已注册
sqlContext.registerRDDAsTable(entries, "entries")
可以使用查询
sqlContext.sql("SELECT * FROM entries WHERE myDateFilter(when)")
有关更多详细信息,请参阅此示例。
在 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")
在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")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.