UDF函数开发

标准函数(UDF):以一行数据中的一列或者多列数据作为参数然后返回解雇欧式一个值的函数,同样也可以返回一个复杂的对象,例如array,map,struct。

聚合函数(UDAF):接受从零行到多行的零个到多个列,然后返回单一值。例如sum函数。

生成函数(UDTF):接受零个或者多个输入,然后产生多列或者多行输出。

udf函数开发

当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数,用户自定义函数(user defined function),针对单条记录。编写一个UDF,需要继承UDF类,并实现evaluate()函数。在查询执行过程中,查询中对应的每个应用到这个函数的地方都会对这个类进行实例化。对于每行输入都会调用到evaluate()函数。而evaluate()函数处理的值会返回给Hive。同时用户是可以重载evaluate方法的。Hive会像Java的方法重载一样,自动选择匹配的方法。

准备数据:

littlebigdata.txt

edward capriolo,edward@media6degrees.com,2-12-1981,209.191.139.200,M,10
bob,bob@test.net,10-10-2004,10.10.10.1,M,50
sara connor,sara@sky.net,4-5-1974,64.64.5.1,F,2

创建表:

create table if not exists littlebigdata(
name string,
email string,
bday string,
ip string,
gender string,
anum int
)
row format delimited fields terminated by ',';

加载数据:

load data local inpath 'littlebigdata.txt' into table littlebigdata;

代码示例:

import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.junit.Test; public class UDFZodiacSign extends UDF { private SimpleDateFormat df ; public UDFZodiacSign() {
df = new SimpleDateFormat("MM-dd-yyyy");
} public String evaluate(Date bday){
return evaluate(bday.getMonth(),bday.getDay());
} public String evaluate(String bday){
Date date =null;
try{
date = df.parse(bday);
}
catch(Exception ex){
System.out.println("异常");
ex.printStackTrace();
return null;
}
return evaluate(date.getMonth()+1,date.getDay());
} public String evaluate(Integer month,Integer day){
if(month ==1){
if(day<20){
return "Capricorn";
}else{
return "Aquarius";
}
}
if(month ==2){
if(day<19){
return "Capricorn";
}else{
return "Pisces";
}
}
if(month ==3){
if(day<20){
return "Pisces";
}else{
return "Aries";
}
}
if(month ==4){
if(day<20){
return "Aries";
}else{
return "Taurus";
}
}
if(month ==5){
if(day<20){
return "Taurus";
}else{
return "Gemini";
}
}
if(month ==6){
if(day<21){
return "Gemini";
}else{
return "Cancer";
}
}
if(month ==7){
if(day<22){
return "Cancer";
}else{
return "Leo";
}
}
if(month ==8){
if(day<23){
return "Leo";
}else{
return "Virgo";
}
}
if(month ==9){
if(day<22){
return "Virgo";
}else{
return "Libra";
}
}
if(month ==10){
if(day<24){
return "Libra";
}else{
return "Scorpio";
}
}
if(month ==11){
if(day<22){
return "Scorpio";
}else{
return "Sagittarius";
}
}
if(month ==12){
if(day<22){
return "Sagittarius";
}else{
return "Capricorn";
}
} return null;
}
@Test
public void test() { UDFZodiacSign aa = new UDFZodiacSign();
String str = aa.evaluate("01-10-2004");
System.out.println(str);
} }

udf代码示例

函数使用

加载:

add jar testUDF-0.0.1-SNAPSHOT.jar;
create temporary function zodiac as "cn.rtmap.bigdata.hive.testUDF.udf.UDFZodiacSign";

查询:

select name,bday,zodiac(bday) from littlebigdata;

结果:

edward capriolo    2-12-1981    Capricorn
bob 10-10-2004 Libra
sara connor 4-5-1974 Aries

注意:这个地方可能有报错,反正我是遇到了!

解决办法:

1,修改jdk的版本 可能版本太高。
2,删除META-INF 文件中*.SF的文件,这个是依赖包有冲突导致的。
3.在MANIFEST.MF 中添加Main-Class: cn.rtmap.bigdata.hive.testUDF.udf.UDFZodiacSign,这个可以在maven中创建好。

UDF四种加载方式

第一种:

是最常见但也不招人喜欢的方式是使用ADD JAR(s)语句,之所以说是不招人喜欢是,通过该方式添加的jar文件只存在于当前会话中,当会话关闭后不能够继续使用该jar文件,最常见的问题是创建了永久函数到metastore中,再次使用该函数时却提示ClassNotFoundException。所以使用该方式每次都要使用ADD JAR(s)语句添加相关的jar文件到Classpath中。

第二种:

是修改hive-site.xml文件。修改参数hive.aux.jars.path的值指向UDF文件所在的路径。,该参数需要手动添加到hive-site.xml文件中。
<property>
<name>hive.aux.jars.path</name>
<value>file:///jarpath/all_new1.jar,file:///jarpath/all_new2.jar</value>
</property>

 第三种:

是在${HIVE_HOME}下创建auxlib目录,将UDF文件放到该目录中,这样hive在启动时会将其中的jar文件加载到classpath中。(推荐)

 第四种:

是设置HIVE_AUX_JARS_PATH环境变量,变量的值为放置jar文件的目录,可以拷贝${HIVE_HOME}/conf中的hive-env.sh.template为hive-env.sh文件,并修改最后一行的#export HIVE_AUX_JARS_PATH=为exportHIVE_AUX_JARS_PATH=jar文件目录来实现,或者在系统中直接添加HIVE_AUX_JARS_PATH环境变量。

最新文章

  1. Sharif University CTF 2016 - Smooth As Silk
  2. 干货之UIButton的title和image自定义布局
  3. Digest [IAB_SRI_Online_Advertising_Effectiveness]
  4. easyui的datagrid和panel如何让标题动态改变?
  5. Android开发需要注意的地方
  6. Linux字符串函数集
  7. 汇编语言学习——第二章 寄存器(CPU工作原理)
  8. TPL异步并行编程之任务超时
  9. 用border或者div制作三角形等图形
  10. 对着java并发包写.net并发包之原子类型实现
  11. AngularJS1.X学习笔记11-服务
  12. 全文检索-Elasticsearch (三) DSL
  13. vue中样式的典型操作(:class,:style)
  14. day16 函数的用法:内置函数,匿名函数
  15. Linux上的文件管理类命令(2)
  16. 将string转为同名类名,方法名。(c#反射)
  17. myeclise 安装
  18. 喊山 BFS
  19. 【转】基于easyui开发Web版Activiti流程定制器详解(一)——目录结构
  20. JS中浮点数精度误差解决

热门文章

  1. Mathematica之基本操作
  2. JQuery基本选择器和基本动画方法总结
  3. leetcode-happy number implemented in python
  4. Chem 3D模型的参数值更改方法
  5. 细说多线程之Thread VS Runnable
  6. shared_ptr &amp; weak_ptr
  7. less-!important关键字
  8. ZOJ 1648 Circuit Board(计算几何)
  9. js实现查询关键词,使其高亮
  10. Spoken English Practice(not always estimating your status in other&#39;s hearts. you will lose yourself when you live in other&#39;s look. do your best and walk on you own way.)