HIVE自定义UDTF函数
Posted 牧码文
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HIVE自定义UDTF函数相关的知识,希望对你有一定的参考价值。
UDTF函数
文章目录
HIVE提供了丰富的内置函数,但是对于一些复杂逻辑还是需要自定义函数来实现,对此,HIVE也提供了一些自定义的接口和类。
UDF:一进一出,一对一的关系数据
UDTF:一进多处,一对多的关系数据
UDAF:多进一出,多对一的关系数据
一、继承GenericUDTF类
实现三个方法:
initialize方法
两个作用:
-
初始化参数,判断参数类型是否符合要求
-
设置输出列和类型
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);
process方法
处理数据,通过forward方法将数据写出,没写出一次,代表为一行,可以传入一个数组
forward(result);
close方法
顾名思义,打扫干净,下一位
二、源码解析
因为在之前的版本UDTF的initialize方法提供的是:
@Override
public StructObjectInspector initialize(ObjectInspector[] argOIs) throws UDFArgumentException
return super.initialize(argOIs);
现在上述的方式已经不推荐了,改作了:
@Override
public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException
return super.initialize(argOIs);
将一个参数数组转变为了一个结构对象检查器,这个怎么使用的?
看一下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);
如果需要校验参数类型,通过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");
其实就是将参数列表封装成了StructObjectInspector对象,如果想要校验参数,那么通过上述的方式,可以看到,调用getAllStructFieldRefs方法,获取所有的输入列列表,遍历就可以取到参数列表了
inputFields.get(i).getFieldObjectInspector();
process方法就是处理逻辑的方法,每次输出一个forward,就会分割为一列
String[] result = comment.split(":");
forward(result);
三、例子
按照逗号进行分割字符串,输出列
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
注意在UDTF函数中,会出现传入数据异常的问题,在这里我并没有校验参数,在实际生产中是需要校验参数的。
以上是关于HIVE自定义UDTF函数的主要内容,如果未能解决你的问题,请参考以下文章
Hive--10---函数----自定义函数 (UDF-UDAF-UDTF)