Hive的UDF包括3种:UDF(User-Defined Function)、UDAF(User-Defined Aggregate Function)和UDTF(User-Defined Table-Generating Function),Hive只支持Java编写UDF,其他的编程语言只能通过select transform转化为流来与Hive交互。

UDF(User-Defined Function):支持一个输入产生一个输出。继承自org.apache.hadoop.hive.ql.exec.UDF,并实现evaluate方法。

1、代码实现

import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;

public class Lower2Upper extends UDF {

  public Text evaluate(Text text,String up_low){
    if(text==null){
      return null;
    }else if(up_low.equals("lowercase")){
      return new Text(text.toString().toLowerCase());
    }else if(up_low.equals("uppercase")){
      return new Text(text.toString().toUpperCase());
    }else{
      return null;
    }
  }

}

2、打包,并放到hive所在的机器

3、进入hive的shell,用add jar命令把jar包导入到hive的环境变量中,用create temporary function as 命令基于jar包中的类创建临时函数。

hive>add jar /home/user/lowupper.jar;
hive>create temporary function lowupper as 'com.upit.hive.udf.Low2Upper';
hive>select lowupper(name,'uppercase') from userinfo;

4、销毁不再需要的函数

hive>drop temporary function lowupper;

注意:lowupper为临时的函数,所以每次进入都需要add jar以及create temporary操作。

UDAF(User-Defined Aggregate Function):支持多个输入一个输出。继承org.apache.hadoop.hive.ql.exec.UDAF类,实现org.apache.hadoop.hive.ql.exec.UDAFvaluator接口。UDAFvaluator接口有5个方法,分别如下:

  • int  方法负责对中间结果实现初始化
  • iterate  接收传入的参数,并进行内部的轮转,其返回类型为boolean
  • terminaePartial  没有参数,负责返回iterate函数轮转后的数据
  • merge  接收terminatePartial的返回结果,合并接收的蹭值,返回类型为boolean
  • terminate  返回最终结果

import org.apache.hadoop.hive.ql.exec.NumericUDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
import org.apache.hadoop.hive.serde2.io.DoubleWritable;

public class UDAFSum_Sample extends NumericUDAF {
  public static class Evaluator implements UDAFEvaluator{
    private boolean mEmpty;
    private double mSum;
    public Evaluator(){
      super();
      init();
    }
    @Override
    public void init() {
      mSum=0;
      mEmpty=true;
    }
    public boolean iterate(DoubleWritable o){
      if(o!=null){
        mSum+=o.get();
        mEmpty=false;
      }
      return true;
    }
    public DoubleWritable terminatePartial(){
      return mEmpty?null:new DoubleWritable(mSum);
    }
    public boolean merge(DoubleWritable o){
      if(o!=null){
        mSum+=o.get();
        mEmpty=false;
      }
      return true;
    }
    public DoubleWritable terminate(){
      return mEmpty?null:new DoubleWritable(mSum);
    }
  }
}

关于UDAF开发应注意以下几点:

  • import org.apache.hadoop.hive.ql.exec.UDAF以及org.apache.hadoop.hive.ql.exec.UDAFEvaluator包都是必需的。
  • 函数类需要继承UDAF类,内部类Evaluator实现UDAFEvaluator接口。
  • Evaluator需要实现init、iterate、terminatePartial、merge、terminate这几个函数。
  • init函数类似于构造函数,用于UDAF的初始化。
  • iterate接收传入的参数,并进行内部的轮转,其返回类型为boolean。
  • terminatePartial无参数,其为iterate函数轮转结束后返回的轮转数据,iterate和terminatePartial类似于Hadoop的Combiner.
  • merge接收terminatePartial的返回结果,进行数据merge操作,其返回类型为boolean。
  • terminate返回最终的聚集函数结果。

UDTF(User-Defined Table-Generating Function):支持一个输入多个输出。

1、如何实现UDTF

继承org.apache.hadoop.hive.ql.udf.generic.GenericUDTF。

实现initialize, process, close三个方法

UDTF首先会调用initialize方法,此方法返回UDTF的返回行的信息(返回个数,类型)。初始化完成后,会调用process方法,对传入的参数进行处理,可以通过forword()方法把结果返回。最后close()方法调用,对需要清理的方法进行清理

2、实例

如下代码对形如key:value;key:value;格式的字符串分拆成key,value,返回结果为key, value两个字段

import java.util.ArrayList;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

public class ExplodeMap extends GenericUDTF {
  @Override
  public void close() throws HiveException {}

  @Override
  public StructObjectInspector initialize(ObjectInspector[] args)throws UDFArgumentException {
    if (args.length != 1) {
      throw new UDFArgumentLengthException("ExplodeMap takes only one argument");
    }
    if (args[0].getCategory() != ObjectInspector.Category.PRIMITIVE) {
      throw new UDFArgumentException("ExplodeMap takes string as a parameter");
    }
    ArrayList<String> fieldNames = new ArrayList<String>();
    ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();
    fieldNames.add("col1");
    fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
    fieldNames.add("col2");
    fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
    return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);
  }

  @Override
  public void process(Object[] args) throws HiveException {
    String input = args[0].toString();
    String[] test = input.split(";");
    for (int i = 0; i < test.length; i++) {
      try {
        String[] result = test[i].split(":");
        forward(result);
      } catch (Exception e) {
        continue;
      }
    }
  }
}

3、 如何使用UDTF

3.1、在select中使用UDTF

select explode_map(properties) as (col1,col2) from my_table

不可以添加其他字段使用:select a, explode_map(properties) as (col1,col2) from my_table

不可以嵌套调用:select explode_map(explode_map(properties)) from my_table

不可以和group by/cluster by/distribute by/sort by一起使用:select explode_map(properties) as (col1,col2) from src group by col1, col2

3.2、结合lateral view使用

select src.id, mytable.col1, mytable.col2 from src lateral view explode_map(properties) mytable as col1, col2;

此方法更为方便日常使用。执行过程相当于单独执行了两次抽取,然后union到一个表里。

4、总结

使用lateral view之后,那么col1和col2相当于普通的列,可以参与查询,计算

2、Hive UDF编程实例的更多相关文章

  1. hive udf编程教程

    hive udf编程教程 https://blog.csdn.net/u010376788/article/details/50532166

  2. HIVE: UDF应用实例

    数据文件内容 TEST DATA HERE Good to Go 我们准备写一个函数,把所有字符变为小写. 1.开发UDF package MyTestPackage; import org.apac ...

  3. Hive UDF 用户自定义函数 编程及使用

    首先创建工程编写UDF 代码,示例如下: 1. 新建Maven项目 udf 本机Hadoop版本为2.7.7, Hive版本为1.2.2,所以选择对应版本的jar ,其它版本也不影响编译. 2. po ...

  4. 2.13 Hive中自带Function使用及自定义UDF编程

    UDF:User Definition Function 一.function #查看自带的函数 hive (db_hive)> show functions; #查看一个函数的详细用法 hiv ...

  5. HIVE udf实例

    本例中udf来自<hive编程指南>其中13章自定义函数中一个例子. 按照步骤,第一步,建立一个项目,创建 GenericUDFNvl 类. /** * 不能接受第一个参数为null的情况 ...

  6. Hive UDF初探

    1. 引言 在前一篇中,解决了Hive表中复杂数据结构平铺化以导入Kylin的问题,但是平铺之后计算广告日志的曝光PV是翻倍的,因为一个用户对应于多个标签.所以,为了计算曝光PV,我们得另外创建视图. ...

  7. PHP多进程编程实例

    这篇文章主要介绍了PHP多进程编程实例,本文讲解的是在Linux下实现PHP多进程编程,需要的朋友可以参考下 羡慕火影忍者里鸣人的影分身么?没错,PHP程序是可以开动影分身的!想完成任务,又觉得一个进 ...

  8. c#摄像头编程实例 (转)

    c#摄像头编程实例 摄像头编程 安装摄像头后,一般可以找到一个avicap32.dll文件 这是一个关于设想头的类 using  system;using  System.Runtime.Intero ...

  9. Hive UDF 实验1

    项目中使用的hive版本低于0.11,无法使用hive在0.11中新加的开窗分析函数. 在项目中需要使用到row_number()函数的地方,有人写了udf来实现这个功能. new java proj ...

随机推荐

  1. Python之路,Day9 - 线程、进程、协程和IO多路复用

    参考博客: 线程.进程.协程: http://www.cnblogs.com/wupeiqi/articles/5040827.html http://www.cnblogs.com/alex3714 ...

  2. 常见浏览器bug(针对IE6及更低版本)及其修复方法

    常见bug及其修复方法有以下几种 1.双外边距浮动bug 双外边距浮动bug在IE6及更低版本中常见.所谓双外边距浮动bug是指使任何浮动元素上的外边距加倍.(见下图) 只要将元素的display属性 ...

  3. 普通用户开通sudo权限:xxx is not in the sudoers file.This incident will be reported.的解决方法

    1.切换到root用户下,怎么切换就不用说了吧,不会的自己百度去. 2.添加sudo文件的写权限,命令是: chmod u+w /etc/sudoers 3.编辑sudoers文件 vi /etc/s ...

  4. Bing的Translation API 接入

    参考: https://msdn.microsoft.com/zh-cn/library/mt146806.aspx 首先你需要一个Microsoft的帐号,如果没有在这里注册一下 https://s ...

  5. 《Drools7.0.0.Final规则引擎教程》第4章 注释&错误信息

    注释 像Java开发语言一样,Drools文件中也可以添加注释.注释部分Drools引擎是会将其忽略调的.单行注释使用"//",示例如下: rule "Testing C ...

  6. Java 进阶巩固:什么是注解以及运行时注解的使用

    这篇文章 2016年12月13日星期二 就写完了,当时想着等写完另外一篇关于自定义注解的一起发.结果没想到这一等就是半年多 - -. 有时候的确是这样啊,总想着等条件更好了再干,等准备完全了再开始,结 ...

  7. 从小白开始学习iOS开发

    从事iOS开发不经意间,已经两年过去了,记得当初看到OC是,我根本就不知道那些个东西是什么?从开始学习开机,到一个个英文开始,为了能找到工作,愣是耐下心去坚持看下去. 现在回想起来,很是庆幸我没有放弃 ...

  8. JavaScript动态加载js文件

    /********************************************************************* * JavaScript动态加载js文件 * 说明: * ...

  9. DevOps实践

    云计算 [ 01 ]GitLab+Rancher实践DevOps[转载] [ 02 ]Kubernetes CentOS 7.4搭建Kubernetes 1.8.5集群 kubeadm搭建kubern ...

  10. 启动和连接MySQL服务

    1.服务端启动 1.查看MySQL状态 sudo /etc/init.d/mysql status sudo /etc/init.d/mysql start | stop | restart sudo ...