Spark Sql的UDF和UDAF函数
Spark Sql提供了丰富的内置函数供猿友们使用,辣为何还要用户自定义函数呢?实际的业务场景可能很复杂,内置函数hold不住,所以spark sql提供了可扩展的内置函数接口:哥们,你的业务太变态了,我满足不了你,自己按照我的规范去定义一个sql函数,该怎么折腾就怎么折腾!
这里还是先以Scala实现一个简单的hello world级别的小样为例,来体验udf与udaf的使用好了。
问题
将如下数组:
val bigData = Array("Spark","Hadoop","Flink","Spark","Hadoop","Flink",
"Spark","Hadoop","Flink","Spark","Hadoop","Flink")
中的字符分组聚合并计算出每个字符的长度及字符出现的个数。正常结果
如下:
+------+-----+------+
| name|count|length|
+------+-----+------+
| Spark| | |
| Flink| | |
|Hadoop| | |
+------+-----+------+
注:‘spark’ 这个字符的长度为5 ,共出现了4次。
分析
- 自定义个一个求字符串长度的函数
自定义的sql函数,与scala中的普通函数一样,只不过在使用上前者需要先在sqlContext中进行注册。 - 自定义一个聚合函数
按照字符串名称分组后,调用自定义的聚合函数实现累加。
啊,好抽象,直接看代码吧!
代码
package com.hand.datasafe import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{Row, SQLContext, SparkSession}
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType /**
* Spark SQL UDAF:user defined aggregation function
* UDF: 函数的输入是一条具体的数据记录,实现上讲就是普通的scala函数-只不过需要注册
* UDAF:用户自定义的聚合函数,函数本身作用于数据集合,能够在具体操作的基础上进行自定义操作
*/
object SparkSQLUDF { def main(args: Array[String]): Unit = { val spark = SparkSession.builder().appName("datasafe").master("local").getOrCreate() val bigData = Array("Spark", "Hadoop", "Flink", "Spark", "Hadoop", "Flink", "Spark", "Hadoop", "Flink", "Spark", "Hadoop", "Flink")
val bigDataRDD = spark.sparkContext.parallelize(bigData) val bigDataRowRDD: RDD[Row] = bigDataRDD.map(line => Row(line))
val structType = StructType(Array(StructField("name", StringType, true)))
val bigDataDF = spark.createDataFrame(bigDataRowRDD, structType)
bigDataDF.printSchema()
bigDataDF.createTempView("bigDataTable") /*
* 通过saprk注册UDF,在scala2.1.x版本UDF函数最多可以接受22个输入参数
*/
spark.udf.register("computeLength", (input: String) => input.length)
spark.sql("select name,computeLength(name) as length from bigDataTable").show //while(true){} spark.udf.register("wordCount", new MyUDAF)
spark.sql("select name,wordCount(name) as count,computeLength(name) as length from bigDataTable group by name ").show
spark.sql("select name,wordCount(name) as count,computeLength(name) as length from bigDataTable group by name ").printSchema() }
}
package com.hand.datasafe import org.apache.spark.sql.Row
import org.apache.spark.sql.expressions.{MutableAggregationBuffer, UserDefinedAggregateFunction}
import org.apache.spark.sql.types._ /**
* 用户自定义函数
*/
class MyUDAF extends UserDefinedAggregateFunction
{
/**
* 指定具体的输入数据的类型
* 自段名称随意:Users can choose names to identify the input arguments - 这里可以是“name”,或者其他任意串
*/
override def inputSchema:StructType = StructType(Array(StructField("name",StringType,true))) /**
* 在进行聚合操作的时候所要处理的数据的中间结果类型
*/
override def bufferSchema:StructType = StructType(Array(StructField("count",IntegerType,true))) /**
* 返回类型
*/
override def dataType:DataType = IntegerType /**
* whether given the same input,
* always return the same output
* true: yes
*/
override def deterministic:Boolean = true /**
* Initializes the given aggregation buffer
*/
override def initialize(buffer:MutableAggregationBuffer):Unit = {buffer()=} /**
* 在进行聚合的时候,每当有新的值进来,对分组后的聚合如何进行计算
* 本地的聚合操作,相当于Hadoop MapReduce模型中的Combiner
*/
override def update(buffer:MutableAggregationBuffer,input:Row):Unit={
buffer() = buffer.getInt()+
} /**
* 最后在分布式节点进行local reduce完成后需要进行全局级别的merge操作
*/
override def merge(buffer1:MutableAggregationBuffer,buffer2:Row):Unit={
buffer1() = buffer1.getInt()+buffer2.getInt()
} /**
* 返回UDAF最后的计算结果
*/
override def evaluate(buffer:Row):Any = buffer.getInt()
}
总结
呼叫spark大神升级udaf实现
为了自己实现一个sql聚合函数,我需要继承UserDefinedAggregateFunction并实现8个抽象方法!8个方法啊!what’s a disaster ! 然而,要想在sql中完成符合特定业务场景的聚合类(a = aggregation)功能,就得udaf。
怎么理解MutableAggregationBuffer呢?就是存储中间结果的,聚合就意味着多条记录的累加等操作。
Spark Sql的UDF和UDAF函数的更多相关文章
- Spark SQL中UDF和UDAF
转载自:https://blog.csdn.net/u012297062/article/details/52227909 UDF: User Defined Function,用户自定义的函数,函数 ...
- Spark SQL概念学习系列之用户自定义函数
不多说,直接上干货! 用户自定义函数 注册udf 我们可以使用Spark 支持的编程语言编写好函数,然后通过Spark SQL 内建的方法传递进来,非常便捷地注册我们自己的UDF 在Scala 和Py ...
- 【Spark篇】---SparkSQL中自定义UDF和UDAF,开窗函数的应用
一.前述 SparkSQL中的UDF相当于是1进1出,UDAF相当于是多进一出,类似于聚合函数. 开窗函数一般分组取topn时常用. 二.UDF和UDAF函数 1.UDF函数 java代码: Spar ...
- Spark(十三)【SparkSQL自定义UDF/UDAF函数】
目录 一.UDF(一进一出) 二.UDAF(多近一出) spark2.X 实现方式 案例 ①继承UserDefinedAggregateFunction,实现其中的方法 ②创建函数对象,注册函数,在s ...
- Databricks 第9篇:Spark SQL 基础(数据类型、NULL语义)
Spark SQL 支持多种数据类型,并兼容Python.Scala等语言的数据类型. 一,Spark SQL支持的数据类型 整数系列: BYTE, TINYINT:表示1B的有符号整数 SHORT, ...
- Spark SQL 用户自定义函数UDF、用户自定义聚合函数UDAF 教程(Java踩坑教学版)
在Spark中,也支持Hive中的自定义函数.自定义函数大致可以分为三种: UDF(User-Defined-Function),即最基本的自定义函数,类似to_char,to_date等 UDAF( ...
- 详解Spark sql用户自定义函数:UDF与UDAF
UDAF = USER DEFINED AGGREGATION FUNCTION Spark sql提供了丰富的内置函数供猿友们使用,辣为何还要用户自定义函数呢?实际的业务场景可能很复杂,内置函数ho ...
- 【Spark篇】---SparkSql之UDF函数和UDAF函数
一.前述 SparkSql中自定义函数包括UDF和UDAF UDF:一进一出 UDAF:多进一出 (联想Sum函数) 二.UDF函数 UDF:用户自定义函数,user defined functio ...
- Kafka:ZK+Kafka+Spark Streaming集群环境搭建(十五)Spark编写UDF、UDAF、Agg函数
Spark Sql提供了丰富的内置函数让开发者来使用,但实际开发业务场景可能很复杂,内置函数不能够满足业务需求,因此spark sql提供了可扩展的内置函数. UDF:是普通函数,输入一个或多个参数, ...
随机推荐
- php if语句判定my查询是否为空
<?php header("Content-type: text/html; charset=utf-8"); $username=$_GET['username']; $p ...
- php -- 文件操作类(文件或文件夹的:创建、删除、复制、移动)
<? /** * 操纵文件类 * * 例子: * FileUtil::createDir('a/1/2/3'); 测试建立文件夹 建一个a/1/2/3文件夹 * FileUtil::create ...
- 通用性能测试过程模型GAME(A)
1.3.1 Goal(定义目标) 制定一个明确而详细的测试目标是性能测试开始的第一步,也是性能测试成功的关键. 本步骤的开始时间:需求获取阶段 本步骤的输入:性能需求意向 本步骤的输出:明确的性能测 ...
- python_cookies
1.将cookies保存到变量中,然后打印cookie中的值 #coding:utf-8 #将cookies保存到变量中,然后打印cookie中的值 import urllib2 import coo ...
- Hibernate_day01--解决配置文件没有提示问题_演示常见错误
解决配置文件没有提示问题 1 可以上网 2 把约束文件引入到eclipse中 (1)在配置文件中复制一句话 重启eclipse开发工具 演示常见错误 1 在映射配置文件中,把name属性值写错了,和实 ...
- ArcGIS -- ArcSDE Lock request conflicts with an established lock
1.查询下列表是否有数据 select * from sde.state_locks; select * from sde.object_locks; select * from sde.layer_ ...
- 面试题思考:解释一下什么叫AOP(面向切面编程)
这种在运行时,动态地将代码切入到类的指定方法.指定位置上的编程思想就是面向切面的编程. AOP是Spring提供的关键特性之一.AOP即面向切面编程,是OOP编程的有效补充. 使用AOP技术,可以将一 ...
- excel如何将一个工作薄中的工作表生成独立的工作薄
excel如何将一个工作薄中的工作表生成独立的工作薄 '用vba代码 Sub 另存所有工作表为工作簿() Dim sht As Worksheet Application.ScreenUpdatin ...
- hdu4122(单调队列)
处理题目中给的日期,然后用单调队列维护 Alice's mooncake shop Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32 ...
- android高仿微信UI点击头像显示大图片效果, Android 使用ContentProvider扫描手机中的图片,仿微信显示本地图片效果
http://www.cnblogs.com/Jaylong/archive/2012/09/27/androidUI.html http://blog.csdn.net/xiaanming/arti ...