自定义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. bootstrap单选框复选框的使用

    <form role="form"> <div class="form-group"> <label class="ch ...

  2. JAVA开发框架

    1.Bootstrap     Bootstrap是美国Twitter公司的设计师Mark Otto和Jacob Thornton合作基于HTML.CSS.JavaScript 开发的简洁.直观.强悍 ...

  3. 2 大O表示法

    1.大O表示法 表示程序的执行时间或占用空间随数据规模的增长趋势. 算法操作 时间复杂度 线性查找 O(n) 二分查找 O(logn) 无序数组插入 O(1) 无序数组删除 O(n) 有序数组插入 O ...

  4. LeetCode 88. 合并两个有序数组(Merge Sorted Array)

    题目描述 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组. 说明: 初始化 nums1 和 nums2 的元素数量分别为 m ...

  5. PHP 验证5-20位数字加字母的正则(数字和字母缺一不可)!!!

    $pattern = '/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{5,20}$/'; if(!preg_match($pattern,$username)){ re ...

  6. TP框架如何绑定参数。目的进行ajax验证

    TP框架的自动绑定 对于某些操作的情况(例如模型的写入和更新方法),可以支持参数的自动绑定,例如: 首先需要开启DB_BIND_PARAM配置参数: 'DB_BIND_PARAM' => tru ...

  7. 评CSDN上一篇讲述数据迁移的文章“程序员 12 小时惊魂记:凌晨迁移数据出大事故!”

    原文地址:https://blog.csdn.net/csdnnews/article/details/98476886 我的评论:热数据迁移,本不该搞突击,这样一旦出现问题后果不堪设想,多少DBA和 ...

  8. javascript循环语句

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. Python 正则表达式【二】

    关于前向,后向,匹配,非匹配 Matches if ... matches next, but doesn’t consume any of the string. This is called a ...

  10. FICO相关号码范围IMG设定

    一.定义会计文件号码范围——FBN1 二.定义总账检视的文件号码范围——FAGL_DOCNR 三.指派客户科目群组的号码范围 四.定义供应商号码范围——XKN1  五.维护订单号码范围——KONK