hive自定義函數

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

相關文章
相關標籤/搜索