自定義函數包括三種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 <函數名>;接口