Hive UDF开发教程

1 定义

Hive UDF(User Defined Function 用户自定义函数),是在Hive内置的处理函数无法满足用户需求时,由用户自行继承接口实现的单行数据处理函数。

Hive 有两个不同的接口编写 UDF 程序。
1 简单数据类型的 UDF 接口
org.apache.hadoop.hive.ql.exec.UDF

基础 UDF 的函数读取和返回基本类型,即 Hadoop 和 Hive 的基本类型。如 Text、IntWritable、LongWritable、DoubleWritable 等。

2 复杂数据类型的 GenericUDF 接口。
org.apache.hadoop.hive.ql.udf.generic.GenericUDF

GenericUDF 可以处理 Map、List、Set 类型

2 开发

2.1 依赖引入

2.2 简单类型UDF

如果预期输入输出都是int、string和decimal等简单数据类型,实现起来较为简单,只需继承UDF类,实现一个名为evaluate()的方法即可,具体举例如下:

public class UDFtest extends UDF {
    public  String evaluate(String str,Integer size) {
        if (size > str.length()) return str;
        return str.substring(0,size);
    }
}

2.3 复杂类型UDF

GenericUDF使用详解

class ComplexUDFExample extends GenericUDF {
  // 0. ObjectInspector,通常以成员变量的形式被创建
  ListObjectInspector listOI; 
  StringObjectInspector elementOI;
  @Override
  public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
    // 1. 检查该记录是否传过来正确的参数数量
    if (arguments.length != 2) {
      throw new UDFArgumentLengthException("arrayContainsExample only takes 2 arguments: List<T>, T");
    }
    // 2. 检查该条记录是否传过来正确的参数类型
    ObjectInspector a = arguments[0];
    ObjectInspector b = arguments[1];
    if (!(a instanceof ListObjectInspector) || !(b instanceof StringObjectInspector)) {
      throw new UDFArgumentException("first argument must be a list / array, second argument must be a string");
    }
    // 3. 检查通过后,将参数赋值给成员变量ObjectInspector,为了在evaluate()中使用
    this.listOI = (ListObjectInspector) a;
    this.elementOI = (StringObjectInspector) b;
    
    // 4. 检查数组是否包含字符串,是否为字符串数组
    if(!(listOI.getListElementObjectInspector() instanceof StringObjectInspector)) {
      throw new UDFArgumentException("first argument must be a list of strings");
    }
    
    // 5. 用工厂类生成用于表示返回值的ObjectInspector
    return PrimitiveObjectInspectorFactory.javaBooleanObjectInspector;
  }
  
  @Override
  public Object evaluate(DeferredObject[] arguments) throws HiveException {
    
    // get the list and string from the deferred objects using the object inspectors
    List<String> list = (List<String>) this.listOI.getList(arguments[0].get());
    String arg = elementOI.getPrimitiveJavaObject(arguments[1].get());
    
    // check for nulls
    if (list == null || arg == null) {
      return null;
    }
    
    // see if our list contains the value we need
    for(String s: list) {
      if (arg.equals(s)) return new Boolean(true);
    }
    return new Boolean(false);
  }

  @Override
  public String getDisplayString(String[] arg0) {
    return "arrayContainsExample()"; // this should probably be better
  }

3 测试

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值