假如说我们有这样的数据:
1,zhangsan:18:beijing|male|it,2000
2,lisi:28:beijing|female|finance,4000
3,wangwu:38:shanghai|male|project,20000
假如这些数据由某个应用系统产生在hdfs的如下目录中:/log/data/2018-08-21/
需要放进hive中去做数据挖掘分析
可以先建一张外部表,跟原始数据所在的目录关联;
create external table t_user_info(id int,user_info string,salary int)
row format delimited
fields terminated by ','
location '/log/data/2018-08-21';
原来的数据不方便做细粒度的分析挖掘,所以字段需要拆分,用hive的自带的函数不方便
所以我们需要自定义一个函数来实现拆解功能。
这样的数据是很难分析的,所以我们就希望使用下面这样的函数:
select
id,my_func(info,1) as name,my_func(info,2) as age,my_func(info,3) as addr,
my_func(info,4) as sex
from
t_user_info
where salary>4000
我们在hive中建立一个函数名,跟java程序去关联起来,然后我们在sql中使用函数的时候,本质上会把我们的数据作为输入传给java程序,然后java程序再返回一个结果出来。
所以我们需要去写一个java类,而且我们需要去导入hive的jar包。(打成jar包的时候可以不选lib包因为hive中已经有了。)
package com.test.hive.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
public class UserInfoParser extends UDF{
//重写evaluate方法
//数据:zhangsan:18:beijing|male|it
public String evaluate(String field,int index) {
//这里的第一个参数是正则,|在正则中有特殊含义,所以需要转义
String replaceAll = field.replaceAll("\\|", ":");
String[] split = replaceAll.split(":");
return split[index-1];
}
//一旦打成jar包丢给hive之后就不好测试了,我们先测试一下
//打jar包的时候留着也没事,因为hive也不会调用
//打成jar包的时候可以不选lib包因为hive中已经有了。
public static void main(String[] args) {
UserInfoParser u = new UserInfoParser();
String str = u.evaluate("zhangsan:18:beijing|male|it,2000",1);
System.out.println(str);
}
}
打成jar包之后,服务端我们不好操作,但是在客户端连上服务器也一样,我们需要将jar包添加到它的classpath下。
可是我们的客户端已经在运行了,还能添加吗?
答案是可以的,我们可以在客户端运行的时候添加classpath
add jar /root/udf.jar
经过上述的操作我们就把classpath添加到classpath下了,就可以用了。
接下来我们需要去写函数然后和类关联起来。
create temporary function uinf_parse as 'com.test.hive.udf.UserInfoParser';
我们可以使用
show functions;
来查看函数
接下来我们需要创建一个表,并导入数据:
create table t_user_info(id int,user_info string,salary int)
row format delimited
fields terminated by ',';
load data local inpath '/root/user.data' into table t_user_info;
接下来我们测试一下我们的程序能不能用:
select
id,
uinf_parse(user_info,1) as name,
uinf_parse(user_info,2) as age,
uinf_parse(user_info,3) as sex,
uinf_parse(user_info,4) as job,
salary
from t_user_info;
我们可以将查出来的内容存入另一个表中生成一种规范的格式:
create table t_u_info
as
select
id,
uinf_parse(user_info,1) as name,
uinf_parse(user_info,2) as age,
uinf_parse(user_info,3) as address,
uinf_parse(user_info,4) as sex,
uinf_parse(user_info,5) as project,
salary
from t_user_info;