1.為什么需要UDF? 1)、因為內(nèi)部函數(shù)沒法滿足需求。 2)、hive它本身就是一個靈活框架,允許用自定義模塊功能,如可以自定義UDF、serde、輸入輸出等。 2.UDF是什么? UDF:user difine function,用戶自定義函數(shù),一對一。常用 udaf:user define aggregate function,用戶自定義聚合函數(shù),多對一。 udtf:user define table_generate function,用戶自定義表生成函數(shù),一對多。 3.怎么編寫UDF函數(shù)?? 1)、該類需要繼承UDF,重寫evaluate(),允許該方法重載。 2)、也可以繼承 generic UDF,需要重寫 initliaze() 、 getDisplay() 、 evaluate() 4.UDF的使用 第一種:(當前session有效) package edu.qianfeng.UDF;
import org.apache.hadoop.hive.ql.exec.UDF;
/** * 使用Java 自定義UDF * @author lyd * *1603 1603_class */ public class FirstUDF extends UDF{ //重寫evaluate() public String evaluate(String str){ //判斷 if(str == null){ return null; } return str+"_class"; } } 1、添加自定UDF的jar包 hive>add jar /home/h2h.jar; 2、創(chuàng)建臨時函數(shù) hive>create temporary function myfunc as "edu.qianfeng.UDF.FirstUDF"; 3、測試是否添加好: show functions; select myfunc("1603"); 4、確定無用時可以刪除: drop temporary function myfunc; 第二種:(當前session有效)package edu.qianfeng.UDF; import org.apache.hadoop.hive.ql.exec.UDF; import org.json.JSONException; import org.json.JSONObject;
public class KeyToValue extends UDF{ public String evaluate(String str,String key){ if(str == null || key == null){ return null; } //sex=1&hight=180&weight=130&sal=28000 //{sex:} String str1 = str.replace("=", ":"); String str2 = str1.replace("&", ","); String str3 = "{"+str2+"}"; String value = ""; try { JSONObject jo = new JSONObject(str3); value = jo.get(key).toString(); } catch (JSONException e) { e.printStackTrace(); } return value; } public static void main(String[] args) { System.out.println(new KeyToValue().evaluate("sex=1&hight=180&weight=130&sal=28000&facevalue=900", "facevalue")); } } 1、添加自定UDF的jar包(hive.aux.jars.path在該目錄下的jar會在hive啟動時自動加載) <property> <name>hive.aux.jars.path</name> <value>$HIVE_HOME/auxlib</value> </property> cp /home/h2h.jar $HIVE_HOME/auxlib/ 2、啟動hive,創(chuàng)建臨時函數(shù) hive>create temporary function ktv as "edu.qianfeng.UDF.KeyToValue"; 3、測試是否添加好: show functions; select myfunc("1603"); 4、確定無用時可以刪除: drop temporary function myfunc; 第三種:(當前session有效)1、創(chuàng)建一個初始化文件: vi ./init-hive add jar /home/h2h.jar; create temporary function ktv1 as "edu.qianfeng.UDF.KeyToValue"; 2、啟動使用命令: hive -i ./init-hive 3、測試是否添加好: show functions; select myfunc("1603"); 4、確定無用時可以刪除: drop temporary function myfunc; 第四種:(做成永久性)package edu.qianfeng.UDF; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import org.apache.hadoop.hive.ql.exec.UDF;
/** * 根據(jù)出生年月獲取周歲 * @author lyd * * 2000-04-19 17 * 2000-04-20 16 * 2000-04-21 16 * */ public class BirthdayToAge extends UDF{ public static void main(String[] args) { System.out.println(new BirthdayToAge().evaluate("2000-04-20")); } public String evaluate(String birthday){ if(birthday == null || birthday.trim().isEmpty()){ return null; } String age = ""; try { //獲取出生時間 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); //獲取出生的時間戳 long bithdayts = sdf.parse(birthday).getTime(); //獲取今天的時間戳 long nowts = new Date().getTime(); //獲取從出生到現(xiàn)在有多少秒 long alldays = (nowts - bithdayts)/1000/60/60/24; if(alldays < 0){ return null; } //判斷閏年 int birthdayyear = Integer.parseInt(birthday.split("-")[0]); Calendar ca = Calendar.getInstance(); int nowyear = ca.get(Calendar.YEAR); //循環(huán)找 int rnday = 0; for (int i = birthdayyear; i < nowyear; i++) { if((i%400 == 0) || (i%4 == 0 && i%100 != 0)){ rnday ++ ; } } //將閏年的額天數(shù)減掉 age = (alldays-rnday)/365+""; } catch (ParseException e) { return null; } return age; } } 需要對源碼編譯。 1)將寫好的Jave文件拷貝到~/install/hive-0.8.1/src/ql/src/java/org/apache/hadoop/hive/ql/UDF/ cd ~/install/hive-0.8.1/src/ql/src/java/org/apache/hadoop/hive/ql/UDF/ ls -lhgt |head 2)修改~/install/hive-0.8.1/src/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java,增加import和RegisterUDF import com.meilishuo.hive.UDF.UDFIp2Long; //添加import registerUDF("ip2long", UDFIp2Long.class, false); //添加register 3)在~/install/hive-0.8.1/src下運行ant -Dhadoop.version=1.0.1 package cd ~/install/hive-0.8.1/src ant -Dhadoop.version=1.0.1 package 4)替換exec的jar包,新生成的包在/hive-0.8.1/src/build/ql目錄下,替換鏈接 cp hive-exec-0.8.1.jar /hadoop/hive/lib/hive-exec-0.8.1.jar.0628 rm hive-exec-0.8.1.jar ln -s hive-exec-0.8.1.jar.0628 hive-exec-0.8.1.jar 5)重啟進行測試
|