Hive 函数UDF开发以及永久注册UDF函数

explode: (把一串数据转换成多行的数据)
创建一个文本:
[hadoop@ruozehadoop000 data]$ vi hive-wc.txt
hello,world,welcome
hello,welcome

创建一个表,并导入文本内容
create table hive_wc(sentence string); 
load data local inpath '/home/hadoop/data/hive-wc.txt' into table hive_wc;
hello,world,welcome
hello,welcome

求每个单词出现的个数
 1) 获取每个单词  split(sentence,",")
["hello","world","welcome"]
["hello","welcome"] 
 结果输出:
"hello"
"world"
"welcome" 
"hello"
"welcome"
通过聚合语法进行计算:
select word, count(1) as c
from (select explode(split(sentence,",")) as word from hive_wc) t
group by word ;

json:工作中常用
创建一张表 rating_json,上传数据,并查看前十行数据信息
create table rating_json(json string);
load data local inpath '/home/hadoop/data/rating.json' into table rating_json;
对json的数据进行处理

jason_tuple 是一个UDTF是 Hive0.7版本引进的
select json_tuple(json,"movie","rate","time","userid") as (movie,rate,time,userid) 
from rating_json limit 10;

作业:

准备一份数据:
[hadoop@ruozehadoop000 data]$ more hive_row_number.txt
1,18,ruoze,M
2,19,jepson,M
3,22,wangwu,F
4,16,zhaoliu,F
5,30,tianqi,M
6,26,wangba,F

创建表并导入数据:
create table hive_rownumber(id int,age int, name string, sex string)
row format delimited fields terminated by ',';

load data local inpath '/home/hadoop/data/hive_row_number.txt' into table hive_rownumber;

要求:查询出每种性别中年龄最大的2条数据 
order by是全局的排序,做不到分组内的排序
组内进行排序,就要用到窗口函数or分析函数

分析函数
select id,age,name,sex
from
(select id,age,name,sex,
row_number() over(partition by sex order by age desc) as rank
from hive_rownumber) t
where rank<=2;
输出结果:

User-Defined Functions : UDF
 UDF: 一进一出  upper  lower substring
 UDAF:Aggregation  多进一出  count max min sum ...
 UDTF: Table-Generation  一进多出

工具:IDEA + Maven

定义函数功能:输入xxx,输出Hello xxx

自定义UDF函数的步骤:
以下部分摘自学长博客,略作修改。

创建一个新的项目


填写相关信息:


修改参数路径:


填写项目名称和保存路径:


更新完后删除:


修改:


页面可以打开就行:

https://repository.cloudera.com/artifactory/cloudera-repos/


本次环境需要下载:

Index of cloudera-repos/org/apache/hadoop/hadoop-common

新建一个类:



功能:输入XXX,输出Hello xxx -> 输入一个东西,输出的时候前面带Hello

自定义UDF函数的步骤:

             1)定义一个类 extends UDF (继承UDF)

导入继承UDF

-- 现在我们输出一个,Hello:若泽:Jepson

  1. package com.RUOZEdata.bigdata;
  2. import org.apache.hadoop.hive.ql.exec.UDF;
  3. public class HelloUDF extends UDF {
  4. public String evaluate(String input){
  5. return "Hello:" + input;
  6. }
  7. public String evaluate(String input, String input2) {
  8. return "Hello:" + input + ":" + input2;
  9. }
  10. public static void main(String[] args) {
  11. HelloUDF udf = new HelloUDF();
  12. System.out.println(udf.evaluate("若泽", "Jepson"));
  13. }
  14. }
图结果:


打包:


打包成功:


上传jar包到 /home/hadoop/lib目录下:



第一种:创建临时函数。如在hive CLI执行下面命令:

-- 以下命令Hive执行,创建 sayHello

add jar /home/hadoop/lib/hive-1.0.jar;

CREATE TEMPORARY FUNCTION sayHello AS 'com.ruozedata.bigdata.HelloUDF';

这里的红色字体是从UDF这里 复制 reference,注意红色字体旁边需要有引号


-- 执行语句

add jar /home/hadoop/lib/hive-1.0.jar;
CREATE TEMPORARY FUNCTION sayHello AS 'com.ruozedata.bigdata.HelloUDF'; 

-- show functions 查找是否存在:

进入另一会话查看,发现没有。

我们使用的是TEMPORARY:仅对当前session(黑窗口)有效,所以在其他窗口打开是没用的
CREATE TEMPORARY FUNCTION sayHello AS 'com.ruozedata.bigdata.HelloUDF'; 

-- 在第一个窗口使用 list jars可以查看到刚刚添加的jar包


-- 如果从新开一个窗口,会有要去add jar比较麻烦,我们需要在Hive的目录底下创建一个文件,把jar包拷贝过去

然后再创建新的表测试,是否正确,临时的创建,从启后都会失效。



第二种 修改源代码,重编译,注册函数。这种方法可以永久性的保存udf函数,但是风险很大
-- 首先需要把本地文件hive-1.0.jar放到HDFS上,然后在创建永久的函数的时候需要指定HDFS目录
hdfs dfs -put /home/hadoop/lib/hive-1.0.jar /lib/
-- 创建函数,我这里和若泽的端口号可能不同我这里是9000,他这里是8020


不确定端口号的可以使用命令 hive > desc formatted 查看一张表,


-- 如果在location后面看到这一串不认识的东西 511023ea-b9d8-46d3-aff8-c1e3613f61c9 就是HDFS上的
-- show functions 查看是否有sayruozehello
-- 查询是否存在:

-- 再打开一个窗口,查看是否能查询的到 show functions
-- 再查询,这次查询不连接hive3库,直接查询,查询的时候要在信息前面加hive3的库名,第一次会转换,从HDFS上加载进来

-- 永久注册,会注册到元数据内,我们进行元数据查询。



-- 我们启动Hive会有很多函数,都是怎么来的呢?进入函数查看源码,了解底层的机


个人总结:
    上述两种方法,第一种方法仅仅是临时函数无法满足生产上的需求,总会有情况需要提供稳定的udf函数。而第二种方法虽然满足了需求,但是存在较大的风险,易造成hive的异常。根据官方的说法, hive0.13版本以后(包过0.13)是支持注册永久函数的,而且提供了注册的方法。但注意创建注册udf函数的时候,要注意环境模式


猜你喜欢

转载自blog.csdn.net/qq_37408712/article/details/81042669