小小千想和您聊一聊

当前位置: 首页> 技术分享> 大数据编程之UDF函数

大数据编程之UDF函数

  1.为什么需要UDF?

  1)、因为内部函数没法满足需求。

  2)、hive它本身就是一个灵活框架,允许用自定义模块功能,如可以自定义UDF、serde、输入输出等。

  2.UDF是什么?

  UDF:user difine function,用户自定义函数,一对一。常用 udaf:user define aggregate function,用户自定义聚合函数,多对一。 udtf:user define table_generate function,用户自定义表生成函数,一对多。

  3.怎么编写UDF函数??

  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、创建临时函数

  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,创建临时函数

  hive>create temporary function ktv as "edu.qianfeng.UDF.KeyToValue";

  3、测试是否添加好:

  show functions;

  select myfunc("1603");

  4、确定无用时可以删除:

  drop temporary function myfunc;

  第三种:(当前session有效)

  1、创建一个初始化文件:

  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;

/**
 * 根据出生年月获取周岁
 * @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();
			//获取从出生到现在有多少秒
			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);
			//循环找
			int rnday = 0;
			for (int i = birthdayyear; i < nowyear; i++) {
				if((i%400 == 0) || (i%4 == 0 && i%100 != 0)){
					rnday ++ ;
				}
			}
			//将闰年的额天数减掉
			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)重启进行测试

上一篇:HTML5工具初识之网页编辑器

下一篇:Hive分区和分桶

QQ技术交流群

千锋大数据官方①群
857910996

加入群聊