自定义函数包括三种UDF、UDAF、UDTF
UDF(User-Defined-Function) 一进一出
UDAF(User- Defined Aggregation Funcation) 汇集函数,多进一出。Count/max/min
UDTF(User-Defined Table-Generating Functions) 一进多出,如lateral view explore()
使用方式 :在HIVE会话中add 自定义函数的jar文件,而后建立function继而使用函数java
UDFapache
这是普通的用户自定义函数。接受单行输入,并产生单行输出。
一、UDF函数能够直接应用于select语句,对查询结构作格式化处理后,再输出内容。
二、编写UDF函数的时候须要注意一下几点:
a)自定义UDF须要继承org.apache.hadoop.hive.ql.UDF。
b)须要实现evaluate函数,evaluate函数支持重载。
注:UDF只能实现一进一出的操做,若是须要实现多进一出,则须要实现UDAFide
udf实现对字符串的截取函数
package hive; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.hadoop.hive.ql.exec.UDF; public class GetCmsID extends UDF{ public String evaluate(String url){ String cmsid = null; if(url ==null || "".equals(url)){ return cmsid; } Pattern pat = Pattern.compile("topicId=[0-9]+"); Matcher matcher = pat.matcher(url); if(matcher.find() ){ cmsid=matcher.group().split("topicId=")[1]; } return cmsid; } public String evaluate(String pattern,String url ){ String cmsid = null; if(url ==null || "".equals(url)){ return cmsid; } Pattern pat = Pattern.compile(pattern+"[0-9]+"); Matcher matcher = pat.matcher(url); if(matcher.find() ){ cmsid=matcher.group().split(pattern)[1]; } return cmsid; } public static void main(String[] args) { String url = "http://www.baidu.com/cms/view.do?topicId=123456"; GetCmsID getCmsID = new GetCmsID(); System.out.println(getCmsID.evaluate(url)); System.out.println(getCmsID.evaluate("topicId=",url)); } }
UDAFoop
用户定义汇集函数(User-defined aggregate function)。接受多行输入,并产生单行输出。好比MAX,COUNT函数。lua
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():无参数,函数在部分聚合完成后被调用。当hive但愿获得部分记录的聚合结果时,此函数被调用。
merge():接收terminatePartial的返回结果,用于合并先前获得的部分聚合结果(也能够理解为分块记录的聚合结果),其返回类型为boolean
terminate():返回最终的汇集函数结果url
merge的输入参数类型和terminatePartial函数的返回值类型必须是一致的。code
packagecom.oserp.hiveudf; importorg.apache.hadoop.hive.ql.exec.UDAF; importorg.apache.hadoop.hive.ql.exec.UDAFEvaluator; importorg.apache.hadoop.hive.serde2.io.DoubleWritable; importorg.apache.hadoop.io.IntWritable; public class HiveAvg extends UDAF { public static class AvgEvaluate implements UDAFEvaluator { public static class PartialResult { public intcount; public doubletotal; public PartialResult() { count = 0; total = 0; } } private PartialResult partialResult; @Override public void init() { partialResult = new PartialResult(); } public boolean iterate(IntWritable value) { // 此处必定要判断partialResult是否为空,不然会报错 // 缘由就是init函数只会被调用一遍,不会为每一个部分汇集操做去作初始化 //此处若是不加判断就会出错 if (partialResult==null) { partialResult =new PartialResult(); } if (value !=null) { partialResult.total =partialResult.total +value.get(); partialResult.count=partialResult.count + 1; } return true; } public PartialResult terminatePartial() { returnpartialResult; } public boolean merge(PartialResult other) { partialResult.total=partialResult.total + other.total; partialResult.count=partialResult.count + other.count; return true; } public DoubleWritable terminate() { return newDoubleWritable(partialResult.total /partialResult.count); } } }
部署运行继承
1).把程序打包放到目标机器上去
2).进入hive客户端,添加jar包:
hive> add jar /home/sfd/udf_test.jar
3).建立临时函数:
hive> create temporary function <函数名>
> as 'java全类名';
4).销毁临时函数:
hive> drop temporary function <函数名>;接口