117°

hive自定义函数

Hive中有三种UDF:

1、用户定义函数(user-defined function)UDF;

2、用户定义聚集函数(user-defined aggregate function,UDAF);

3、用户定义表生成函数(user-defined table-generating function,UDTF)。

UDF操作作用于单个数据行,并且产生一个数据行作为输出。大多数函数都属于这一类(比如数学函数和字符串函数)。

UDAF 接受多个输入数据行,并产生一个输出数据行。像COUNT和MAX这样的函数就是聚集函数。

UDTF 操作作用于单个数据行,并且产生多个数据行-------一个表作为输出。lateral view explore()

简单来说:

UDF:返回对应值,一对一

UDAF:返回聚类值,多对一

UDTF:返回拆分值,一对多

自定义udf函数

1.继承UDF类

2.重写evaluate方法

3.把项目打成jar包

4.hive中执行命令add jar /home/jrjt/dwetl/PUB/UDF/udf/GetProperty.jar;

5.创建函数create temporary function get_pro as 'jd.Get_Property'//jd.jd.Get_Property为类路径;

#创建永久的只需要去掉temporary

class SimpleUDFExample extends UDF {

public Text evaluate(Text input) {

return new Text("Hello " + input.toString());

}

}

自定义UDAF函数

多行进一行出,如sum()、min(),用在group by时

1.必须继承

  org.apache.hadoop.hive.ql.exec.UDAF(函数类继承)

  org.apache.hadoop.hive.ql.exec.UDAFEvaluator(内部类Evaluator实现UDAFEvaluator接口)

 

2.Evaluator需要实现 init、iterate、terminatePartial、merge、terminate这几个函数

  init():类似于构造函数,用于UDAF的初始化

  iterate():接收传入的参数,并进行内部的轮转,返回boolean

  terminatePartial():无参数,其为iterate函数轮转结束后,返回轮转数据,类似于hadoop的Combiner

  merge():接收terminatePartial的返回结果,进行数据merge操作,其返回类型为boolean

  terminate():返回最终的聚集函数结果

自定义UDTF函数

继承org.apache.hadoop.hive.ql.udf.generic.GenericUDTF,实现initialize, process, close三个方法。

UDTF首先会调用initialize方法,此方法返回UDTF的返回行的信息(返回个数,类型)。

初始化完成后,会调用process方法,真正的处理过程在process函数中,在process中,每一次forward()调用产生一行;如果产生多列可以将多个列的值放在一个数组中,然后将该数组传入到forward()函数。最后close()方法调用,对需要清理的方法进行清理。

 

下面切分”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("只需要一个参数");

}

if (args[0].getCategory() != ObjectInspector.Category.PRIMITIVE) {

throw new UDFArgumentException("参数非字符串类型");

}

//定义返回列及类型k:string,v:string

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(":");

//返回kv数组

forward(result);

} catch (Exception e) {

continue;

}

}

}

}

使用方法

UDTF有两种使用方法,一种直接放到select后面,一种和lateral view一起使用。

1、直接select中使用

select explode_map(field) as (col1,col2) from tb;

注意:不可以添加其他字段使用、不可以嵌套调用、不可以和group by/cluster by/distribute by/sort by一起使用

2:和lateral view一起使用

select tb1.id, tb2.col1, tb2.col2 from tb1 lateral view explode_map(field) tb2 as col1, col2;

此方法相当于单独执行了两次抽取,然后union到一个表里。

本文由【阿伦哥-】发布于开源中国,原文链接:https://my.oschina.net/zlhblogs/blog/3010105

全部评论: 0

    我有话说: