在Spark中,也支持Hive中的自定义函数。自定义函数大致可以分为三种:

  • UDF(User-Defined-Function),即最基本的自定义函数,类似to_char,to_date等
  • UDAF(User- Defined Aggregation Funcation),用户自定义聚合函数,类似在group by之后使用的sum,avg等
  • UDTF(User-Defined Table-Generating Functions),用户自定义生成函数,有点像stream里面的flatMap

自定义一个UDF函数需要继承UserDefinedAggregateFunction类,并实现其中的8个方法

示例

import org.apache.spark.sql.Row
import org.apache.spark.sql.expressions.{MutableAggregationBuffer, UserDefinedAggregateFunction}
import org.apache.spark.sql.types.{DataType, StringType, StructField, StructType} object GetDistinctCityUDF extends UserDefinedAggregateFunction{
/**
* 输入的数据类型
* */
override def inputSchema: StructType = StructType(
StructField("status",StringType,true) :: Nil
)
/**
* 缓存字段类型
* */
override def bufferSchema: StructType = {
StructType(
Array(
StructField("buffer_city_info",StringType,true)
)
)
}
/**
* 输出结果类型
* */
override def dataType: DataType = StringType
/**
* 输入类型和输出类型是否一致
* */
override def deterministic: Boolean = true
/**
* 对辅助字段进行初始化
* */
override def initialize(buffer: MutableAggregationBuffer): Unit = {
buffer.update(,"")
}
/**
*修改辅助字段的值
* */
override def update(buffer: MutableAggregationBuffer, input: Row): Unit = {
//获取最后一次的值
var last_str = buffer.getString()
//获取当前的值
val current_str = input.getString()
//判断最后一次的值是否包含当前的值
if(!last_str.contains(current_str)){
//判断是否是第一个值,是的话走if赋值,不是的话走else追加
if(last_str.equals("")){
last_str = current_str
}else{
last_str += "," + current_str
}
}
buffer.update(,last_str) }
/**
*对分区结果进行合并
* buffer1是机器hadoop1上的结果
* buffer2是机器Hadoop2上的结果
* */
override def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = {
var buf1 = buffer1.getString()
val buf2 = buffer2.getString()
//将buf2里面存在的数据而buf1里面没有的数据追加到buf1
//buf2的数据按照,进行切分
for(s <- buf2.split(",")){
if(!buf1.contains(s)){
if(buf1.equals("")){
buf1 = s
}else{
buf1 += s
}
}
}
buffer1.update(,buf1)
}
/**
* 最终的计算结果
* */
override def evaluate(buffer: Row): Any = {
buffer.getString()
}
}

注册自定义的UDF函数为临时函数

def main(args: Array[String]): Unit = {
/**
* 第一步 创建程序入口
*/
val conf = new SparkConf().setAppName("AralHotProductSpark")
val sc = new SparkContext(conf)
val hiveContext = new HiveContext(sc)
  //注册成为临时函数
hiveContext.udf.register("get_distinct_city",GetDistinctCityUDF)
  //注册成为临时函数
hiveContext.udf.register("get_product_status",(str:String) =>{
var status =
for(s <- str.split(",")){
if(s.contains("product_status")){
status = s.split(":")().toInt
}
}
})
}

Spark学习之路 (十九)SparkSQL的自定义函数UDF的更多相关文章

  1. Spark学习之路 (十九)SparkSQL的自定义函数UDF[转]

    在Spark中,也支持Hive中的自定义函数.自定义函数大致可以分为三种: UDF(User-Defined-Function),即最基本的自定义函数,类似to_char,to_date等 UDAF( ...

  2. Spark(十三)SparkSQL的自定义函数UDF与开窗函数

    一 自定义函数UDF 在Spark中,也支持Hive中的自定义函数.自定义函数大致可以分为三种: UDF(User-Defined-Function),即最基本的自定义函数,类似to_char,to_ ...

  3. Spark学习之路(九)—— Spark SQL 之 Structured API

    一.创建DataFrame和Dataset 1.1 创建DataFrame Spark中所有功能的入口点是SparkSession,可以使用SparkSession.builder()创建.创建后应用 ...

  4. Spark学习之路 (九)SparkCore的调优之数据倾斜调优

    摘抄自:https://tech.meituan.com/spark-tuning-pro.html 数据倾斜调优 调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题——数据倾斜,此时Sp ...

  5. Spark学习之路 (九)SparkCore的调优之数据倾斜调优[转]

    调优概述 有的时候,我们可能会遇到大数据计算中一个最棘手的问题--数据倾斜,此时Spark作业的性能会比期望差很多.数据倾斜调优,就是使用各种技术方案解决不同类型的数据倾斜问题,以保证Spark作业的 ...

  6. 嵌入式Linux驱动学习之路(十九)触摸屏驱动、tslib测试

    触摸屏使用流程: 1. 按下产生中断. 2.在中断处理程序中启动AD转换XY坐标. 3.AD转换结束并产生AD中断. 4. 在AD的中断处理函数中上报信息,启动定时器. 5. 定时器时间到后进入中断, ...

  7. IOS学习之路十九(JSON与Arrays 或者 Dictionaries相互转换)

    今天写了个json与Arrays 或者 Dictionaries相互转换的例子很简单: 通过 NSJSONSerialization 这个类的 dataWithJSONObject: options: ...

  8. JavaWeb学习记录(十九)——jstl自定义标签库之传统标签

    一.传统标签 (1)JSP引擎将遇到自定义标签时,首先创建标签处理器类的实例对象,然后按照JSP规范定义的通信规则依次调用它的方法. public void setPageContext(PageCo ...

  9. JavaWeb学习记录(十九)——jstl自定义标签之简单标签

    一.简单标签共定义了5个方法: setJspContext方法 setParent和getParent方法 setJspBody方法 doTag方法 二.方法介绍 osetJspContext方法 用 ...

随机推荐

  1. Servlet (三)HttpServletResponse

    package cn.sasa.serv; import java.io.IOException; import javax.servlet.ServletException; import java ...

  2. SQL查询优化:详解SQL Server非聚集索引(转载)

    本文是转载,原文地址 http://tech.it168.com/a2011/1228/1295/000001295176.shtml 在SQL SERVER中,非聚集索引其实可以看作是一个含有聚集索 ...

  3. 微信小程序首支视频广告片发布

    自2017年1月9日上线以来,微信小程序瞬间引爆网络,又迅速归于平静.对这个“无需安装.触手可及.用完即走.无需卸载”的小程序,微信从一开始就对它寄予了无限期望.在公布一系列规则更改后,微信小程序终于 ...

  4. 帝国cms添加修改会员字段时字段名不能带数字,否则注册页会出现空白

    这几天ytkah在整帝国cms会员模块,根据客户需求添加不同的字段,这个相对不难,可还是遇到了点问题.当时添加会员字段时,在字段名用数字“1”来代表第一次,如下图的字段名“1rwsdy” 但是添加以后 ...

  5. what's the python之基本运算符及字符串、列表、元祖、集合、字典的内置方法

    计算机可以进行的运算有很多种,运算按种类可分为算数运算.比较运算.逻辑运算.赋值运算.成员运算.身份运算.字符串和列表的算数运算只能用+和*,字典没有顺序,所以不能进行算数运算和比较运算.比较运算中= ...

  6. Python3学习之路~3.2 递归、函数式编程、高阶函数、匿名函数、嵌套函数

    1 递归 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. def calc(n): print(n) if int(n / 2) == 0: return n r ...

  7. Python创建目录

    需要包含os模块进来,使用相关函数即可实现目录的创建 1.创建目录要用到的函数: (1)os.path.exists(path) 判断一个目录是否存在 (2)os.makedirs(path) 多层创 ...

  8. 003-RFC关于媒体类型说明

    一.概述 RFC-822   Standard for ARPA Internet text messages [ARPA互连网文本信息标准]RFC-2045 MIME Part 1: Format ...

  9. 微信小程序:wx.navigateBack页面返回传参

    场景(比如:商城选地址,选优惠券): 在[页面A]中调用wx.navigateTo方法跳转到[页面B] 然后从[页面B]返回[页面A], 并将[页面B]中的一些数据传回[页面A] wx.navigat ...

  10. 【RPC】综述

    RPC定义 RPC(Remote Procedure Call)全称远程过程调用,它指的是通过网络,我们可以实现客户端调用远程服务端的函数并得到返回结果.这个过程就像在本地电脑上运行该函数一样,只不过 ...