自定义udaf函数的代码框架

 //首先继承一个类AbstractGenericUDAFResolver,然后实现里面的getevaluate方法
public GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters) throws SemanticException {} //在类里面再定义一个内部类继承GenericUDAFEvaluator并重写里面的几个方法 public ObjectInspector init(Mode m, ObjectInspector[] parameters) throws HiveException; abstract AggregationBuffer getNewAggregationBuffer() throws HiveException; public void reset(AggregationBuffer agg) throws HiveException; public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException; public Object terminatePartial(AggregationBuffer agg) throws HiveException; public void merge(AggregationBuffer agg, Object partial) throws HiveException; public Object terminate(AggregationBuffer agg) throws HiveException; //方法的具体使用说明在实例代码中说明

自己实现count聚合函数java代码

public class Sum extends AbstractGenericUDAFResolver {
//创建log对象,用于抛出错误和异常
static final Log log = LogFactory.getLog(Sum.class.getName()); //判断sql语句传入的参数的个数和类型,并将其返回相应的类型
@Override
public GenericUDAFEvaluator getEvaluator(TypeInfo[] info) throws SemanticException {
//判断参数的个数是否符合要求
if (info.length != 1) {
throw new UDFArgumentTypeException(info.length - 1, "exactly one parameter expected");
} //判断传入的参数类型
if (info[0].getCategory() != ObjectInspector.Category.PRIMITIVE) {
throw new UDFArgumentTypeException(0, "only primitive argument is expected but " +
info[0].getTypeName() + "is passed");
} //对传入的参数类型进行进一步的判断是否是我们需求的数据的类型
switch (((PrimitiveTypeInfo) info[0]).getPrimitiveCategory()) {
case BYTE:
case SHORT:
case INT:
case LONG:
case FLOAT:
case DOUBLE:
return new SumRes();
default:
throw new UDFArgumentTypeException(0, "only numric type is expected but " + info[0].getTypeName() + "is passed");
}
} public static class SumRes extends GenericUDAFEvaluator { //创建变量存储中间结果
//input:每一步执行时传入的参数
//output:每一步执行时输出的结果数据的类型
//input和output都只是指定的输入输出的数据类型而已,和数据计算本身无关
//result是聚合的结果的数据,和用于particial2和final阶段的结果输出,genuine不同的业务要求指定不同的类型等
private PrimitiveObjectInspector input;
private PrimitiveObjectInspector output;
private LongWritable result; //对各个阶段都会首先调用一下该方法,并且对输入输出数据初始化 /**
*Mode:
* partial1 : map阶段 会调用 init -> iterate -> partialterminate
* partial2 : combiner阶段 会调用 init -> merge -> partialterminate
* final : reduce阶段 会调用 init -> merge -> terminate
* complete : 只有map没有reduce阶段 会调用 init -> iterate -> terminate
*/
@Override
public ObjectInspector init(Mode m, ObjectInspector[] parameters) throws HiveException {
assert parameters.length == 1;
super.init(m,parameters); //init input
//将传入的参数赋值给定义的input输入变量
if (m == Mode.PARTIAL1 || m == Mode.COMPLETE) {
input = (PrimitiveObjectInspector)parameters[0];
}else {
input = (PrimitiveObjectInspector)parameters[0];
} //init output
//返回中间聚合,或最终结果的数据的类型
if (m == Mode.PARTIAL1 || m == Mode.COMPLETE) {
output = PrimitiveObjectInspectorFactory.writableLongObjectInspector;
}else {
output = PrimitiveObjectInspectorFactory.writableLongObjectInspector;
}
//result用于实际接收聚合结果数据
result = new LongWritable();
return output;
} //中间缓存的暂存结构,用于接收中间运行时需要暂存的变量数据
static class AggregateAgg implements AggregationBuffer{
Long sum;
}
@Override
public AggregationBuffer getNewAggregationBuffer() throws HiveException {
AggregateAgg result = new AggregateAgg();
reset(result);
return result;
} //刷新缓存重置暂存数据,重用jvm
@Override
public void reset(AggregationBuffer agg) throws HiveException {
AggregateAgg myAgg = (AggregateAgg)agg;
myAgg.sum = 0L;
} //对map端传入的每一条数据进行处理
@Override
public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException {
assert parameters.length == 1;
Object param = parameters[0];
if (param != null) {
AggregateAgg myAgg = (AggregateAgg)agg;
myAgg.sum ++;
}
} //返回map阶段对每一条数据处理后的数据
@Override
public Object terminatePartial(AggregationBuffer agg) throws HiveException {
AggregateAgg myAgg = (AggregateAgg)agg;
result.set(myAgg.sum);
return result;
} //在combiner和reduce时候回调用,对map输出的结果进行聚合,即每一条数据调用一下,依次将数据累加到之前的结果上
@Override
public void merge(AggregationBuffer agg, Object partial) throws HiveException {
if (partial != null) {
AggregateAgg myAgg = (AggregateAgg)agg;
myAgg.sum += PrimitiveObjectInspectorUtils.getLong(partial,input);
}
} //使用变量接收最终的结果数据,并将数据进行返回
@Override
public Object terminate(AggregationBuffer agg) throws HiveException {
AggregateAgg myAgg = (AggregateAgg)agg;
result.set(myAgg.sum);
return result;
}
}
}

hive自定义udaf函数的更多相关文章

  1. 关于CDH5.2+ 添加hive自定义UDAF函数的方法

  2. hive自定义UDTF函数叉分函数

    hive自定义UDTF函数叉分函数 1.介绍 从聚合体日志中需要拆解出来各子日志数据,然后单独插入到各日志子表中.通过表生成函数完成这一过程. 2.定义ForkLogUDTF 2.1 HiveUtil ...

  3. 048 SparkSQL自定义UDAF函数

    一:程序 1.需求 实现一个求平均值的UDAF. 这里保留Double格式化,在完成求平均值后与系统的AVG进行对比,观察正确性. 2.SparkSQLUDFDemo程序 package com.sc ...

  4. Hive自定义UDAF详解

    遇到一个Hive需求:有A.B.C三列,按A列进行聚合,求出C列聚合后的最小值和最大值各自对应的B列值.这个需求用hql和内建函数也可完成,但是比较繁琐,会解析成几个MR进行执行,如果自定义UDAF便 ...

  5. (转)Hive自定义UDAF详解

    UDAF有两种,第一种是比较简单的形式,利用抽象类UDAF和UDAFEvaluator,暂不做讨论.主要说一下第二种形式,利用接口GenericUDAFResolver2(或者抽象类AbstractG ...

  6. Spark(十三)【SparkSQL自定义UDF/UDAF函数】

    目录 一.UDF(一进一出) 二.UDAF(多近一出) spark2.X 实现方式 案例 ①继承UserDefinedAggregateFunction,实现其中的方法 ②创建函数对象,注册函数,在s ...

  7. hive自定义函数UDF UDTF UDAF

    Hive 自定义函数 UDF UDTF UDAF 1.UDF:用户定义(普通)函数,只对单行数值产生作用: UDF只能实现一进一出的操作. 定义udf 计算两个数最小值 public class Mi ...

  8. Hive 自定义函数(转)

    Hive是一种构建在Hadoop上的数据仓库,Hive把SQL查询转换为一系列在Hadoop集群中运行的MapReduce作业,是MapReduce更高层次的抽象,不用编写具体的MapReduce方法 ...

  9. Hive 自定义函数

    hive 支持自定义UDF,UDTF,UDAF函数 以自定义UDF为例: 使用一个名为evaluate的方法 package com.hive.custom; import org.apache.ha ...

随机推荐

  1. C#如何生成setup安装文件

    当前项目状况如图: ,如何把test1打包成setup文件,用户安装后即可完成相应功能. 第一,右击“解决方案test1”->添加“新建项目”->“其他项目类型”->“安装和部署”- ...

  2. Java实验课:命令行参数是什么?

    命令行参数:在命令行中给定的参数就是命令行参数.(即从输入位置角度理解). 命令行的参数 1. 什么是命令行的参数? 如: java Test1 365 156 "China" ( ...

  3. Vue 新手学习笔记:vue-element-admin 之安装,配置及入门开发

    所属专栏: Vue 开发学习进步 说实话都是逼出来的,对于前端没干过ES6都不会的人,vue视频也就看了基础的一些但没办法,接下来做微服务架构,前端就用 vue,这块你负责....说多了都是泪,脚手架 ...

  4. 记一次期待已久的渗透 从phpcms到thinkphp

    0X01 前言 这是刚刚开始学习渗透的一个目标吧 这个站从刚开始学的那一天起,就想把他日下来. 可能是自己的信息收集能力太差了吧,导致一直无从下手 没有进展.这是需要慢慢积累的过程.还需努力学习. 0 ...

  5. [CSP-S模拟测试]:D(暴力+剪枝)

    题目传送门(内部题47) 输入格式 第一行一个正整数$n$.第二行$n$个正整数,表示序列$A_i$. 输出格式 一行一个正整数,表示答案. 样例 样例输入: 530 60 20 20 20 样例输出 ...

  6. win7安装Elasticsearch和Elasticsearch-Head插件

    1.环境搭建 1)Java环境搭建可以参考相关的资料,这里不做详细介绍 2)nodejs环境搭建 到官方网站下载相应的zip包:https://nodejs.org/dist/v8.9.1/node- ...

  7. C++入门经典-例9.4-默认模板参数

    1:默认模板参数就是在类模板定义时设置类型形式参数表中的一个类型参数的默认值,该默认值是一个数据类型.有了默认的数据类型参数后,在定义模板的新类型时就可以不进行指定.代码如下: // 9.4.cpp ...

  8. TCP层accept系统调用的实现分析

    inet_csk_accept函数实现了tcp协议accept操作,其主要完成的功能是,从已经完成三次握手的队列中取控制块,如果没有已经完成的连接,则需要根据阻塞标记来来区分对待,若非阻塞则直接返回, ...

  9. 编写可维护的JavaScript代码(部分)

    平时使用的时VS来进行代码的书写,VS会自动的将代码格式化,所有写了这么久的JS代码,也没有注意到这些点.看了<编写可维护的javascript代码>之后,做了些笔记. var resul ...

  10. koa 项目实战(三)创建测试接口和用户模型

    1.创建测试接口,并引入用户模型 根目录/routes/api/users.js const Router = require('koa-router'); const router = new Ro ...