大数据学习之路36-hive的自定义函数示例,复杂数据解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37050372/article/details/81905777

假如说我们有这样的数据:

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;

猜你喜欢

转载自blog.csdn.net/qq_37050372/article/details/81905777
今日推荐