hive 不但为我们提供了丰富的函数库,而且还提供了允许我们扩展的Java接口(UDF),使我们能便捷的自定义函数,实现更多复杂的功能。如下是几个自定义函数:
几个命令
//查看所有函数
$hive> show functions;
//查看函数的使用方法
$hive> desc function 函数名;
两数和(AddUDF)
/**
* 自定义hive函数
*/
@Description(name = "myadd",
value = "myadd(int a , int b) ==> return a + b ",
extended = "Example:\n"
+ " myadd(1,1) ==> 2 \n"
+ " myadd(1,2,3) ==> 6;")
public class AddUDF extends UDF {
public int evaluate(int a ,int b) {
return a + b ;
}
public int evaluate(int a ,int b , int c) {
return a + b + c;
}
}
自定义日期函数
/**
*自定义日期函数,使用GenericUDF
*/
@Description(name = "ToDate",
value = "toDate()",
extended = "toDate_xxxx-ext")
public class ToDateUDF extends GenericUDF {
@Override
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
return null;
}
@Override
public Object evaluate(DeferredObject[] args) throws HiveException {
//有参数
if(args != null && args.length != 0){
//指定日志对象的格式化串
if(args.length == 1){
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.applyPattern("yyyy/MM/dd hh:mm:ss");
try {
return sdf.parse((String)(args[0].get()));
} catch (ParseException e) {
e.printStackTrace();
}
}
//两个参数,Date date,String frt
else{
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.applyPattern((String)args[1].get());
try {
return sdf.parse((String)args[0].get());
} catch (ParseException e) {
e.printStackTrace();
}
}
}
//无参,返回系统时间对象
else{
return new Date();
}
return null ;
}
@Override
public String getDisplayString(String[] children) {
return "toChar_xxx";
}
}
自定义null值处理函数
/**
* 自定义null值处理函数
*/
public class Nvl extends GenericUDF {
private GenericUDFUtils.ReturnObjectInspectorResolver returnOIResolver;
private ObjectInspector[] argumentOIs;
@Override
public ObjectInspector initialize(ObjectInspector[] arguments)
throws UDFArgumentException {
argumentOIs = arguments;
//检查参数个数
if (arguments.length != 2) {
throw new UDFArgumentLengthException(
"The operator 'NVL' accepts 2 arguments.");
}
returnOIResolver = new GenericUDFUtils.ReturnObjectInspectorResolver(true);
//检查参数类型
if (!(returnOIResolver.update(arguments[0]) && returnOIResolver
.update(arguments[1]))) {
throw new UDFArgumentTypeException(2,
"The 1st and 2nd args of function NLV should have the same type, "
+ "but they are different: \"" + arguments[0].getTypeName()
+ "\" and \"" + arguments[1].getTypeName() + "\"");
}
return returnOIResolver.get();
}
@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
Object retVal = returnOIResolver.convertIfNecessary(arguments[0].get(), argumentOIs[0]);
if (retVal == null) {
retVal = returnOIResolver.convertIfNecessary(arguments[1].get(),
argumentOIs[1]);
}
return retVal;
}
@Override
public String getDisplayString(String[] children) {
StringBuilder sb = new StringBuilder();
sb.append("if ");
sb.append(children[0]);
sb.append(" is null ");
sb.append("returns");
sb.append(children[1]);
return sb.toString();
}
}
使用自定义函数
- 将项目打成jar包并将jar包复制到hive的lib目录下
//以第一个函数为例
$> cp /mnt/hgfs/bigdata/runjars/MyHive.jar /soft/hive/lib
//也可以使用 add
$> add jar /mnt/hgfs/bigdata/runjars/MyHive.jar
- 进入hive,创建临时函数
//创建名为 myadd 的函数
CREATE TEMPORARY FUNCTION myadd AS 'com.yuangh.hive.udf.AddUDF';
- 使用函数
$> select myadd(1, 3);
结果:3
推荐书籍
- 《Apache Hive Essential》
- 《Programing Hive》