在hive中,用户自定义函数(UDF)是一个允许用户扩展HiveQL的强大的功能。用户将自定义的函数加入到用户会话中(交互式的或者通过脚本执行的),它们就会像内置的函数一样使用。
编写UDF的java实现
用户编写一个UDF,首先要继承UDF类并且实现evaluate()
函数。在查询中对应的每个应用到这个函数的地方都会对这个类进行实例化。对于每一行输入都会调用到evaluate()
函数。而evaluate()
函数处理后的值会返回给Hive。需要说明的是,evaluate()
函数的参数和返回值类型只能是Hive可以序列化的数据类型。
java实现生肖udf
package myHiveUDF;
import org.apache.hadoop.hive.ql.exec.UDF;
import java.text.SimpleDateFormat;
import java.util.Date;
public class zodiacUDF extends UDF {
private SimpleDateFormat df ;
private static final String[] zodiacArr
= { "猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊" };
/**
* 构造器
* 设置日期格式
*/
public zodiacUDF() {
df = new SimpleDateFormat("yyyy-MM-dd");
}
/**
* 继承类UDF中的evaluate()函数
* @param date
* @return
*/
public String evaluate(Date date){
return this.zodiac(date.getYear());
}
/**
* 继承类UDF中的evaluate()函数
* @param date
* @return
*/
public String evaluate(String date){
Date dt = null;
try{
dt = df.parse(date);
} catch(Exception ex){
return null;
}
System.out.println(dt.getYear() + 1900);
return this.zodiac(dt.getYear() + 1900);
}
/**
* 计算生肖
* @param year
* @return
*/
private String zodiac(Integer year){
return zodiacArr[year % 12];
}
public static void main(String[] args) {
zodiacUDF zf = new zodiacUDF();
System.out.println(zf.evaluate("1989-10-14"));
}
}
在hive中添加jar包
hive> add jar ~/myHiveUDF.jar;
创建临时函数
hive> create temporary function zodiac as 'myHiveUDF.zodiacUDF';
进行查询
hive> select zodiac("1989-10-14") from dual;
OK
蛇
Time taken: 0.102 seconds, Fetched: 1 row(s)
编写UDF的python实现
编写python脚本
这里,Python 实现的 UDF,需要批量的读入数据,并一对一的批量输出。
# -*- coding: utf-8 -*-
import sys
import datetime
zodiacArr = [ "猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊" ]
for line in sys.stdin:
line = line.strip()
date_time = datetime.datetime.strptime(line,'%Y-%m-%d')
print zodiacArr[ date_time.year % 12 ]
通过 ADD FILE
指令添加至 Hive 中进行注册
hive> add file ~/hiveUDF.py;
通过 TRANSFORM...AS
在 HiveQL 中使用
hive> select transform("1989-10-24") USING 'python hiveUDF.py' AS(zodiac)
> from dual;
OK
蛇
Time taken: 17.092 seconds, Fetched: 1 row(s)
其中,TRANSFORM...AS
的语法如下:
SELECT TRANSFORM (<columns>)
USING 'python <python_script>'
AS (<columns>)
FROM <table>;