hive自定义udaf函数
自定义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函数的更多相关文章
- 关于CDH5.2+ 添加hive自定义UDAF函数的方法
- hive自定义UDTF函数叉分函数
hive自定义UDTF函数叉分函数 1.介绍 从聚合体日志中需要拆解出来各子日志数据,然后单独插入到各日志子表中.通过表生成函数完成这一过程. 2.定义ForkLogUDTF 2.1 HiveUtil ...
- 048 SparkSQL自定义UDAF函数
一:程序 1.需求 实现一个求平均值的UDAF. 这里保留Double格式化,在完成求平均值后与系统的AVG进行对比,观察正确性. 2.SparkSQLUDFDemo程序 package com.sc ...
- Hive自定义UDAF详解
遇到一个Hive需求:有A.B.C三列,按A列进行聚合,求出C列聚合后的最小值和最大值各自对应的B列值.这个需求用hql和内建函数也可完成,但是比较繁琐,会解析成几个MR进行执行,如果自定义UDAF便 ...
- (转)Hive自定义UDAF详解
UDAF有两种,第一种是比较简单的形式,利用抽象类UDAF和UDAFEvaluator,暂不做讨论.主要说一下第二种形式,利用接口GenericUDAFResolver2(或者抽象类AbstractG ...
- Spark(十三)【SparkSQL自定义UDF/UDAF函数】
目录 一.UDF(一进一出) 二.UDAF(多近一出) spark2.X 实现方式 案例 ①继承UserDefinedAggregateFunction,实现其中的方法 ②创建函数对象,注册函数,在s ...
- hive自定义函数UDF UDTF UDAF
Hive 自定义函数 UDF UDTF UDAF 1.UDF:用户定义(普通)函数,只对单行数值产生作用: UDF只能实现一进一出的操作. 定义udf 计算两个数最小值 public class Mi ...
- Hive 自定义函数(转)
Hive是一种构建在Hadoop上的数据仓库,Hive把SQL查询转换为一系列在Hadoop集群中运行的MapReduce作业,是MapReduce更高层次的抽象,不用编写具体的MapReduce方法 ...
- Hive 自定义函数
hive 支持自定义UDF,UDTF,UDAF函数 以自定义UDF为例: 使用一个名为evaluate的方法 package com.hive.custom; import org.apache.ha ...
随机推荐
- hdu 5831 Rikka with Parenthesis II 括号匹配+交换
Rikka with Parenthesis II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- 十大免费SSL证书:网站免费添加HTTPS加密
SSL证书,用于加密HTTP协议,也就是HTTPS.随着淘宝.百度等网站纷纷实现全站Https加密访问,搜索引擎对于Https更加友好,加上互联网上越来越多的人重视隐私安全,站长们给网站添加SSL证书 ...
- $\LaTeX$数学公式大全2
$2\ Math\ Constructs$$\frac{abc}{xyz}$ \frac{abc}{xyz}$f'$ f'$\sqrt{abc}$ \sqrt{abc}$\sqrt[n]{abc}$ ...
- 20165213 Exp6 信息搜集与漏洞扫描
信息搜集与漏洞扫描 一. 实践内容 (1)各种搜索技巧的应用 利用Google Hacking Datebase搜索. 尝试搜索http相关的漏洞,可以看到漏洞的相关信息. 也可以使用过滤器进行过滤, ...
- git忽略提交:.gitignore
在使用Git的过程中,我们喜欢有的文件比如日志,临时文件,编译的中间文件等不要提交到代码仓库,这时就要设置相应的忽略规则,来忽略这些文件的提交. Git 忽略文件提交的方法 有三种方法可以实现忽略Gi ...
- nvl(sum(字段),0) 的时候,能展示数据0,但是group by 下某个伪列的时候,查不到数据(转载)
今天碰到一个比较有疑惑的问题,就是在统计和的时候,我们往往有时候查不到数据,都会再加个 nvl(sum(字段),0) 来显示这个字段,但是如果我们再加个group by ,就算有加入这个 nvl(nu ...
- Session案例-用户登录场景
package com.loaderman.demo; import java.io.IOException; import java.io.PrintWriter; import javax.ser ...
- Linux内存简单汇总
Linux内存主要用来存储系统和应用程序的指令,数据,缓存等 一,内存映射 1,内核给每个进程提供一个独立的虚拟机地址空间,并且这个地址空间是连续的 2,虚拟地址空间内部又被分为内核空间和用户空间 3 ...
- linux/windows/Mac平台生成随机数的不同方法
linux平台,使用rand.Seed() //rand_linux.go package main import ( "math/rand" "time" ) ...
- Windows安装使用npm(Nodejs)
转载参考:https://blog.csdn.net/han0373/article/details/80606487 1:下载 https://nodejs.org/en/ 2:查看是否安装成功 w ...