UDAF:用户自定义聚合函数

Scala 2.10.7,spark 2.0.0

package UDF_UDAF

import java.util

import org.apache.spark.SparkConf
import org.apache.spark.sql.{Row, RowFactory, SparkSession}
import org.apache.spark.sql.expressions.{MutableAggregationBuffer, UserDefinedAggregateFunction}
import org.apache.spark.sql.types.{DataType, DataTypes, StructField, StructType} class UDAF extends UserDefinedAggregateFunction {
/**
* 指定输入字段的字段及类型
*/
override def inputSchema: StructType =
DataTypes.createStructType(Array(DataTypes.createStructField("namexxx",DataTypes.StringType,true))) /**
* 在进行聚合操作的时候所要处理的数据的结果的类型
* */
override def bufferSchema: StructType =
DataTypes.createStructType(Array(DataTypes.createStructField("buffer",DataTypes.IntegerType,true))) /**
* 指定UDAF计算后返回的结果类型
* @return
*/
override def dataType: DataType = DataTypes.IntegerType /**
* 确保一致性 一般用true,用以标记针对给定的一组输入,UDAF是否总是生成相同的结果。
*/
override def deterministic: Boolean = true /**
* 初始化一个内部的自己定义的值,在Aggregate之前每组数据的初始化结果
*/
override def initialize(buffer: MutableAggregationBuffer): Unit = buffer.update(0,0) /**
* 更新 可以认为一个一个地将组内的字段值传递进来 实现拼接的逻辑
* buffer.getInt(0)获取的是上一次聚合后的值
* 相当于map端的combiner,combiner就是对每一个map task的处理结果进行一次小聚合
* 大聚和发生在reduce端.
* 这里即是:在进行聚合的时候,每当有新的值进来,对分组后的聚合如何进行计算
*/
override def update(buffer: MutableAggregationBuffer, input: Row): Unit = buffer.update(0, buffer.getInt(0)+1) /**
* 合并 update操作,可能是针对一个分组内的部分数据,在某个节点上发生的 但是可能一个分组内的数据,会分布在多个节点上处理
* 此时就要用merge操作,将各个节点上分布式拼接好的串,合并起来
* buffer1.getInt(0) : 大聚合的时候 上一次聚合后的值
* buffer2.getInt(0) : 这次计算传入进来的update的结果
* 这里即是:最后在分布式节点完成后需要进行全局级别的Merge操作
*/
override def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = buffer1.update(0, buffer1.getInt(0)+buffer2.getInt(0)) /**
* 最后返回一个和dataType方法的类型要一致的类型,返回UDAF最后的计算结果
*/
override def evaluate(buffer: Row): Any = buffer.getInt(0)
} object UDAF{
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local").setAppName("udaf")
val sparkSession = SparkSession.builder().config(conf).config("spark.sql.warehouse.dir","/test/warehouse").getOrCreate()
val sc = sparkSession.sparkContext val parallelize = sc.parallelize(Array("zhangsan","lisi","wanger","zhaosi","zhangsan","lisi"))
val rowRDD = parallelize.map(s=>RowFactory.create(s)) val fields = new util.ArrayList[StructField]()
fields.add(DataTypes.createStructField("name",DataTypes.StringType,true))
val schema = DataTypes.createStructType(fields) val df = sparkSession.createDataFrame(rowRDD, schema)
df.createOrReplaceTempView("user") sparkSession.udf.register("StringCount",new UDAF()) sparkSession.sql("select name, StringCount(name) as StrCount from user group by name").show() sparkSession.stop() }
}

Spark SQL UDAF示例的更多相关文章

  1. Spark SQL UDF示例

    UDF即用户自定函数,注册之后,在sql语句中使用. 基于scala-sdk-2.10.7,Spark2.0.0. package UDF_UDAF import java.util import o ...

  2. Spark Sql的UDF和UDAF函数

    Spark Sql提供了丰富的内置函数供猿友们使用,辣为何还要用户自定义函数呢?实际的业务场景可能很复杂,内置函数hold不住,所以spark sql提供了可扩展的内置函数接口:哥们,你的业务太变态了 ...

  3. Spark学习之Spark SQL

    一.简介 Spark SQL 提供了以下三大功能. (1) Spark SQL 可以从各种结构化数据源(例如 JSON.Hive.Parquet 等)中读取数据. (2) Spark SQL 不仅支持 ...

  4. Spark SQL External DataSource简介

    随着Spark1.2的发布,Spark SQL开始正式支持外部数据源.这使得Spark SQL支持了更多的类型数据源,如json, parquet, avro, csv格式.只要我们愿意,我们可以开发 ...

  5. Spark SQL 用户自定义函数UDF、用户自定义聚合函数UDAF 教程(Java踩坑教学版)

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

  6. 十一、spark SQL的scala示例

    简介 spark SQL官网:http://spark.apache.org/docs/latest/sql-programming-guide.html sparkSQL是构建在sparkCore之 ...

  7. 二、spark SQL交互scala操作示例

    一.安装spark spark SQL是spark的一个功能模块,所以我们事先要安装配置spark,参考: https://www.cnblogs.com/lay2017/p/10006935.htm ...

  8. Spark SQL中UDF和UDAF

    转载自:https://blog.csdn.net/u012297062/article/details/52227909 UDF: User Defined Function,用户自定义的函数,函数 ...

  9. 详解Spark sql用户自定义函数:UDF与UDAF

    UDAF = USER DEFINED AGGREGATION FUNCTION Spark sql提供了丰富的内置函数供猿友们使用,辣为何还要用户自定义函数呢?实际的业务场景可能很复杂,内置函数ho ...

随机推荐

  1. docker上传自己的镜像

    https://blog.csdn.net/boonya/article/details/74906927 需要注意的就是命名规范 docker push 注册用户名/镜像名

  2. [ZJOI2011]营救皮卡丘

    题目描述 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的踏上了营救皮卡丘的道路. 火箭队一共有N个据点,据点之间存在M条双 ...

  3. grafana备份

    #!/bin/bash #自动备份grafana数据库并上传到云盘 NOWDATE=`date +%Y-%m-%d` YUNPAN_USER=xxxx YUNPAN_PASSWD=XXXXXXXXXX ...

  4. 【Linux】配置SSH Key到GitHub/GitLab

    Linux配置SSH Key到GitHub/GitLab 准备工作 首先检查下本机是否已经安装了SSH,在终端输入ssh即可: 如果没有安装进行yum安装 # yum -y install opens ...

  5. <知识整理>树--堆及其应用

    预备知识: 完全二叉树的定义:一个深度为k数的二叉树(设根节点的深度为1),若二叉树深度从1到k-1层都是满的,而第k层的节点都集中在左边(即第k层不存在两节点之间有空缺),那么此数就被叫做完全二叉树 ...

  6. JavaScript中new实现原理

    JavaScript中new实现原理 1.创建一个空对象 obj 2.将该对象 obj 的原型链 __proto__ 指向构造函数的原型 prototype, 并且在原型链 __proto__ 上设置 ...

  7. c do{}while(0)

    1 goto bool foo(){ int *p = (int*)malloc(5*sizeof(int)); bool bOk = true;//执行并处理错误 if(!fun1()) goto ...

  8. Java第五周学习总结

    学号 2016-2017-2 <Java程序设计>第X周学习总结 教材学习内容总结 1.接口 (1)使用关键字interface来定义一个接口,接口分为接口声明和接口体,例如 interf ...

  9. MapReduce-TextInputFormat 切片机制

    MapReduce 默认使用 TextInputFormat 进行切片,其机制如下 (1)简单地按照文件的内容长度进行切片 (2)切片大小,默认等于Block大小,可单独设置 (3)切片时不考虑数据集 ...

  10. python之路(12)网络编程

    前言 基于网络通信(AF_INET)的socket(套接字)实现了TCP/UDP协议 目录 基于TCP协议的socket 基于UDP协议的socket TCP协议下粘包现象及处理 使用socketse ...