UDAF: 多进一出

GenericUDAFEvaluator : 就是根据job的不同阶段执行不同的方法
Hive通过GenericUDAFEvaluator.Modle来确定job的执行阶段
PARTIAL1: 从原始数据到部分聚合,调用方法iterate和terminatePartial方法
PARTIAL2: 从部分数据聚合到部分数据聚合,会调用merge和terminatePartial
FINAL: 从部分数据聚合到全部数据聚合,会调用merge和terminate
COMPLETE: 从原始数据全部聚合,会调用方法iterate和terminate
除了上面提到的iterate,merge,terminatePartial以外,还有init(初始化并返回,返回值的类型)
getNewAggregationBuffer(获取新的buffer,也就是方法间传递参数的对象),reset(重置buffer对象)
需求: 实现一个自定义的sum函数,要求韩函数支持整型和浮点型的sum操作

简单示例,重写SUM函数

package com.hive.udaf;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.parse.SemanticException;
import org.apache.hadoop.hive.ql.udf.generic.AbstractGenericUDAFResolver;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDAFParameterInfo;
import org.apache.hadoop.hive.serde2.io.DoubleWritable;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.AbstractPrimitiveWritableObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils;
import org.apache.hadoop.io.LongWritable; /**
* @author liuwl
* mysum support float & double
*/
public class mysum extends AbstractGenericUDAFResolver{   public GenericUDAFEvaluator getEvaluator(GenericUDAFParameterInfo info) throws SemanticException { // parameters is all clomuns
if(info.isAllColumns()){
  throw new SemanticException("this function is not support all parameters");
}
// only one clomun parameter
ObjectInspector[] inspectors = info.getParameterObjectInspectors();
if(inspectors.length != 1){
  throw new SemanticException("the parameters is only one clomun");
}
if(inspectors[0].getCategory() != ObjectInspector.Category.PRIMITIVE){
  throw new SemanticException("the parameters must be Basic data types");
}
// input parameter's Category
AbstractPrimitiveWritableObjectInspector woi = (AbstractPrimitiveWritableObjectInspector)inspectors[0];
switch (woi.getPrimitiveCategory()) {
  case INT:
  case LONG:
  case BYTE:
  case SHORT:
    return new udafLong();
  case FLOAT:
  case DOUBLE:
    return new udafDouble();
  default:
    throw new SemanticException("the parameter's Category is not support");
}
  }   /**
  * sum the long data
  */
  public static class udafLong extends GenericUDAFEvaluator{     // define data Category
    public PrimitiveObjectInspector longInputor;     static class sumlongagg implements AggregationBuffer{
      long sum;
      boolean empty;
    }     @Override
    public ObjectInspector init(Mode m, ObjectInspector[] parameters) throws HiveException {       super.init(m, parameters);
      if(parameters.length!=1){
        throw new UDFArgumentException("Argument Exception");
      }
      if(this.longInputor == null){
        this.longInputor=(PrimitiveObjectInspector)parameters[0];
      }
      return PrimitiveObjectInspectorFactory.writableLongObjectInspector;
    }     @Override
    public AggregationBuffer getNewAggregationBuffer() throws HiveException {       sumlongagg slg = new sumlongagg();
      this.reset(slg);
      return slg;
    }     @Override
    public void reset(AggregationBuffer agg) throws HiveException {       sumlongagg slg = (sumlongagg)agg;
      slg.sum = 0;
      slg.empty = true;
    }     @Override
    public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException {       if(parameters.length !=1 ){
        throw new UDFArgumentException("Argument Exception");
      }
      this.merge(agg, parameters[0]);
    }     @Override
    public Object terminatePartial(AggregationBuffer agg) throws HiveException {
      return this.terminate(agg);
    }     @Override
    public void merge(AggregationBuffer agg, Object partial) throws HiveException {       sumlongagg slg = (sumlongagg)agg;
      if(partial != null){
        slg.sum += PrimitiveObjectInspectorUtils.getLong(partial, longInputor);
        slg.empty = false;
      }
    }     @Override
    public Object terminate(AggregationBuffer agg) throws HiveException {       sumlongagg slg = (sumlongagg)agg;
      if(slg.empty){
        return null;
      }
      return new LongWritable(slg.sum);
    }   }   /**
  * sum the double data
  */
  public static class udafDouble extends GenericUDAFEvaluator{     // define data Category
    public PrimitiveObjectInspector doubleInputor;       static class sumdoubleagg implements AggregationBuffer{
        double sum;
        boolean empty;
      }
    @Override
    public ObjectInspector init(Mode m, ObjectInspector[] parameters) throws HiveException {       super.init(m, parameters);
      if(parameters.length!=1){
        throw new UDFArgumentException("Argument Exception");
      }
      if(this.doubleInputor == null){
        this.doubleInputor=(PrimitiveObjectInspector)parameters[0];
      }
      return PrimitiveObjectInspectorFactory.writableDoubleObjectInspector; }     @Override
    public AggregationBuffer getNewAggregationBuffer() throws HiveException {       sumdoubleagg sdg = new sumdoubleagg();
        this.reset(sdg);
        return sdg;
      }     @Override
    public void reset(AggregationBuffer agg) throws HiveException {       sumdoubleagg sdg = (sumdoubleagg)agg;
      sdg.sum = 0;
      sdg.empty = true;
    }     @Override
    public void iterate(AggregationBuffer agg, Object[] parameters) throws HiveException {       if(parameters.length !=1 ){
        throw new UDFArgumentException("Argument Exception");
      }
      this.merge(agg, parameters[0]);
    }     @Override
    public Object terminatePartial(AggregationBuffer agg) throws HiveException {
      return this.terminate(agg);
    }     @Override
    public void merge(AggregationBuffer agg, Object partial) throws HiveException {       sumdoubleagg sdg = (sumdoubleagg)agg;
      if(partial != null){
        sdg.sum += PrimitiveObjectInspectorUtils.getDouble(partial, doubleInputor);
        sdg.empty = false;
      }
    }     @Override
    public Object terminate(AggregationBuffer agg) throws HiveException {       sumdoubleagg sdg = (sumdoubleagg)agg;
      if(sdg.empty){
        return null;
      }
      return new DoubleWritable(sdg.sum);
    }
  }
}

测试

hive (workdb)> add jar /home/liuwl/opt/datas/mysum.jar;
hive (workdb)> create temporary function mysum as 'com.hive.udaf.mysum';
hive (workdb)> select sum(deptno),mysum(deptno) from emp;
结果: _c0  _c1
310  310

Hadoop_UDAF示例的更多相关文章

  1. Swift3.0服务端开发(一) 完整示例概述及Perfect环境搭建与配置(服务端+iOS端)

    本篇博客算是一个开头,接下来会持续更新使用Swift3.0开发服务端相关的博客.当然,我们使用目前使用Swift开发服务端较为成熟的框架Perfect来实现.Perfect框架是加拿大一个创业团队开发 ...

  2. .NET跨平台之旅:将示例站点升级至 ASP.NET Core 1.1

    微软今天在 Connect(); // 2016 上发布了 .NET Core 1.1 ,ASP.NET Core 1.1 以及 Entity Framework Core 1.1.紧跟这次发布,我们 ...

  3. 通过Jexus 部署 dotnetcore版本MusicStore 示例程序

    ASPNET Music Store application 是一个展示最新的.NET 平台(包括.NET Core/Mono等)上使用MVC 和Entity Framework的示例程序,本文将展示 ...

  4. WCF学习之旅—第三个示例之四(三十)

           上接WCF学习之旅—第三个示例之一(二十七)               WCF学习之旅—第三个示例之二(二十八)              WCF学习之旅—第三个示例之三(二十九)   ...

  5. JavaScript学习笔记(一)——延迟对象、跨域、模板引擎、弹出层、AJAX示例

    一.AJAX示例 AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网页应用的开发技术.改善用户体验,实现无刷新效 ...

  6. XAMARIN ANDROID 二维码扫描示例

    现在二维码的应用越来越普及,二维码扫描也成为手机应用程序的必备功能了.本文将基于 Xamarin.Android 平台使用 ZXing.Net.Mobile  做一个简单的 Android 条码扫描示 ...

  7. iOS之ProtocolBuffer搭建和示例demo

    这次搭建iOS的ProtocolBuffer编译器和把*.proto源文件编译成*.pbobjc.h 和 *.pbobjc.m文件时,碰到不少问题! 搭建pb编译器到时没有什么问题,只是在把*.pro ...

  8. Android种使用Notification实现通知管理以及自定义通知栏(Notification示例四)

    示例一:实现通知栏管理 当针对相同类型的事件多次发出通知,作为开发者,应该避免使用全新的通知,这时就应该考虑更新之前通知栏的一些值来达到提醒用户的目的.例如我们手机的短信系统,当不断有新消息传来时,我 ...

  9. oracle常用函数及示例

    学习oracle也有一段时间了,发现oracle中的函数好多,对于做后台的程序猿来说,大把大把的时间还要学习很多其他的新东西,再把这些函数也都记住是不太现实的,所以总结了一下oracle中的一些常用函 ...

随机推荐

  1. 关于Javascript的使用参考

    DOM编程>1.js重要的作用就是可以让用户可以与网页元素进行交互操作-->JS精华之所在 >2.DOM编程也是ajax的基础 >3.DOM(文档对象模型),是HTML与XML ...

  2. C#之关机事件

    一.背景 做了个APP,通过向下位机发送串口数据,然后通过串口去控制多路光源,现在的问题来了,若是电脑强行关机,而APP又没在电脑关机前做任何动作,导致电脑已经关机了,而下位机控制的灯源还在工作.所以 ...

  3. 【bzoj4326】[NOIP2015]运输计划

    题目描述 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家物流公司, 该 ...

  4. C和指针 第九章 字符串 字符 字节

    C语言中没有字符串类型,字符串是以NUL结尾的字符数组组成的. 高级字符串查找: //计算字符串起始部分,有多少字符是在group中 size_t strspn(char const * str, c ...

  5. str.format

    #使用str.format()函数 #使用'{}'占位符 print('I\'m {},{}'.format('Hongten','Welcome to my space!')) >>&g ...

  6. php魔术方法和魔术常量

    1.__construct() 实例化对象时被调用, 当__construct和以类名为函数名的函数同时存在时,__construct将被调用,另一个不被调用. 2.__destruct() 当删除一 ...

  7. 文本框value联动修改

    <input id="ipt-edit" value="" /><input id="ipt-target" value= ...

  8. java开发JDBC连接数据库详解

    JDBC连接数据库 好文一定要让大家看见 •创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机) ...

  9. SQL Server 2008登录错误:无法连接到(local)解决方法

    在一些朋友安装完SQL Server 2008之后大多会遇到连接出错的问题比如:SQL Server 2008登录错误:无法连接到(local)等等相关问题,本文将详细介绍解决方法,需要的朋友可以参考 ...

  10. 15.django之Django-Rest-Framework

    1.首先安装Django-Rest-Framework pip3 install djangorestframework pip3 install markdown Markdown为可视化 API ...