• HIVE自定义UDTF函数


    UDTF函数

    HIVE提供了丰富的内置函数,但是对于一些复杂逻辑还是需要自定义函数来实现,对此,HIVE也提供了一些自定义的接口和类。
    UDF:一进一出,一对一的关系数据
    UDTF:一进多处,一对多的关系数据
    UDAF:多进一出,多对一的关系数据

    一、继承GenericUDTF类

    实现三个方法:

    initialize方法

    两个作用:

    1. 初始化参数,判断参数类型是否符合要求

    2. 设置输出列和类型

      ArrayList<String> fieldNames = new ArrayList<String>();
      ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();
      
      fieldNames.add("col1");  // 列名为col1
      fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);  // 类型String
      fieldNames.add("col2");
      fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
    process方法

    处理数据,通过forward方法将数据写出,没写出一次,代表为一行,可以传入一个数组

    forward(result);
    
    • 1
    close方法

    顾名思义,打扫干净,下一位

    二、源码解析

    因为在之前的版本UDTF的initialize方法提供的是:

    @Override
    public StructObjectInspector initialize(ObjectInspector[] argOIs) throws UDFArgumentException {
      return super.initialize(argOIs);
    }
    
    • 1
    • 2
    • 3
    • 4

    现在上述的方式已经不推荐了,改作了:

    @Override
    public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
    
    return super.initialize(argOIs);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    将一个参数数组转变为了一个结构对象检查器,这个怎么使用的?

    看一下super的实现:

    public StructObjectInspector initialize(StructObjectInspector argOIs)
          throws UDFArgumentException {
      List<? extends StructField> inputFields = argOIs.getAllStructFieldRefs();
      ObjectInspector[] udtfInputOIs = new ObjectInspector[inputFields.size()];
      for (int i = 0; i < inputFields.size(); i++) {
        udtfInputOIs[i] = inputFields.get(i).getFieldObjectInspector();
      }
      return initialize(udtfInputOIs);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如果需要校验参数类型,通过size方法校验长度,通过getTypeName方法校验类型

    //对输入参数个数进行进行检验
    if (argOIs.getAllStructFieldRefs().size()!=1) {
            throw new UDFArgumentException ("args must be 1");
        }
    //对输入参数的类型校验
        if(!"string".equals(argOIs.getAllStructFieldRefs().get(0).getFieldObjectInspector().getTypeName().toLower())){
            throw new  UDFArgumentException("args type must be string");
         }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    其实就是将参数列表封装成了StructObjectInspector对象,如果想要校验参数,那么通过上述的方式,可以看到,调用getAllStructFieldRefs方法,获取所有的输入列列表,遍历就可以取到参数列表了

    inputFields.get(i).getFieldObjectInspector();
    
    • 1

    process方法就是处理逻辑的方法,每次输出一个forward,就会分割为一列

    String[] result = comment.split(":");
    forward(result);
    
    • 1
    • 2

    三、例子

    按照逗号进行分割字符串,输出列

    public class ExplodeArray extends GenericUDTF {
        public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
            //定义返回值名称
            List<String> filedNames = new ArrayList<String>();
            //校验返回值类型
            List<ObjectInspector> filedOIs= new ArrayList<ObjectInspector>();
            filedNames.add("col1");
               filedOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
            return  ObjectInspectorFactory.getStandardStructObjectInspector(filedNames,filedOIs);
        }
    
        public void process(Object[] objects) throws HiveException {
            String comment= objects[0].toString();
            String[] str = comment.split(",");
    		for(String s : str){
    		    forward(s);
    		}
        }
    
        public void close() throws HiveException {
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    注意在UDTF函数中,会出现传入数据异常的问题,在这里我并没有校验参数,在实际生产中是需要校验参数的。

  • 相关阅读:
    【博客459】BGP(边界网关协议)-----报文格式
    exness:美元/瑞郎维持承压,空头指向七个月支撑
    Qt-day4
    微软如何打造数字零售力航母系列科普12 - 使用Microsoft Fabric将客户数据带入人工智能时代
    [Deepin] 常用集合
    EPSS 解读:与 CVSS 相比,孰美?
    TensorFlow-Federated简介与安装
    1.数据存储的探究
    ECl@SS学习笔记(1)
    【Linux】22、CPU 评价指标、性能工具、定位瓶颈、优化方法论:应用程序和系统
  • 原文地址:https://blog.csdn.net/weixin_46429290/article/details/126670800