当hive为我们提供的UDF无法满足要求的时候,我们可以开发自己的UDF,我们自己的UDF类需要继承org.apache.hadoop.hive.ql.exec.UDF类
并且在类中实现evaluate方法,当我们在hive中使用自定义的UDF的时候,hive会调用类中的evaluate方法来实现特定的功能。
如下是一个返回字符串的长度的用户自定义UDF:
package com.zx.hive.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
public class UdfTestLength extends UDF{
public Integer evaluate(String s)
{
if(s==null)
{
return null;
}else{
return s.length();
}
}
}
将上面的类打成jar的形式,我使用eclipse直接导出为test-udf.jar包,然后放在/home/zhangxin/hive目录中。
然后,进入到hive的命令行界面:
>hive
//首先将jar包添加到hive中
add jar /home/zhangxin/hive/test-udf.jar
//给UDF定义别名
create temporary function testlength as 'com.zx.hive.udf.UdfTestLength';
//在查询语句中使用UDF
select testlength(a.name) from test_join1 a;
自定义函数可以重载:如下的UDF既可以对两个整数进行相加,也可以对两个double进行相加。
package com.zx.hive.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
public class UdfTestAdd extends UDF{
public Integer evaluate(Integer a,Integer b)
{
return a+b;
}
public Double evaluate(Double a,Double b)
{
return a+b;
}
}
add jar /home/zhangxin/hive/test-udf.jar
//给UDF定义别名
create temporary function testadd as 'com.zx.hive.udf.UdfTestAdd';
//在查询语句中使用UDF
select testadd(1,2) from test_join1 a;
3
select testadd(1.2,2.2) from test_join1 a;
3.4000000000000004
在使用 UDF 的时候,会自动进行类型转换,这个 java 或者 C 中的类型转换有些类似,比如:
SELECT example_add(1, 2.1) FROM src;
的结果是 3.1,这是因为 UDF 将类型为 Int 的参数 “1″ 转换为 double。
类型的隐式转换是通过 UDFResolver 来进行控制的,并且可以根据不同的 UDF 进行不同的控制。
UDF 还可以支持变长的参数,例如 UDFExampleAdd.java:
public class UDFExampleAdd extends UDF {
public Integer evaluate(Integer... a) {
int total = 0;
for (int i=0; i<a.length; i++)
if (a[i] != null) total += a[i];
return total;
} // the same for Double public Double evaluate(Double... a) }
使用例子为:
SELECT example_add(1, 2) FROM src;
SELECT example_add(1, 2, 3) FROM src;
SELECT example_add(1, 2, 3, 4.1) FROM src;
综上,UDF 具有以下特性:
* 用 java 写 UDF 很容易。
* Hadoop 的 Writables/Text 具有较高性能。
* UDF 可以被重载。
* Hive 支持隐式类型转换。
* UDF 支持变长的参数。
* genericUDF 提供了较好的性能(避免了反射)。
Hive的UDF的自定义
猜你喜欢
转载自caodaoxi.iteye.com/blog/1682633
今日推荐
周排行