Hive 之 函数 03-系统内置函数 及 自定义函数
一、 系统内置函数
1.1 查看系统自带的函数
hive (default)> show functions;
1.2 显示自带的函数的用法
hive (default)> desc function func_name;
1.3 详细显示自带的函数的用法
hive (default)> desc function extended func_name;
二、 自定义函数
2.1 概述
当 Hive 提供的内置函数无法满足业务处理需要时,
此时就可以考虑使用用户自定义函数(UDF: user-defined function
)。
根据用户自定义函数类别可以分为以下三种:
○ UDF(User-Defined-Function
)
一进一出
○ UDAF(User-Defined Aggregation Function
)
聚集函数,多进一出
类似于: count
/max
/min
○ UDTF(User-Defined Table-Generating Functions
)
一进多出
如 lateral view explore()
【注】几进几出的依据是 “有多少行”, 进了几行, 出了几行, 而不是参数的个数。
官方文档地址:https://cwiki.apache.org/confluence/display/Hive/HivePlugins
编程步骤:
a. 继承 org.apache.hadoop.hive.ql.UDF
b. 需要实现 evaluate 函数; evaluate 函数支持重载(处理逻辑就在这个函数中实现);
c. 在 hive 的命令行窗口创建函数
a)添加 jar
add jar linux_jar_path
【注】如果放在了 hive/lib 下, 仅第一次需要 add jar, 之后启动 hive 的时候, 会自动加载 lib 下的库;
b)创建 function
create [temporary] function [dbname.]function_name AS class_name;
【注】指定了数据库名称, 在别的数据库中无法使用; 如果不指定, 默认为当前数据库; 如果创建的是 temporary的函数, 那么重启之后函数就失效了。
d. 在 hive 的命令行窗口删除函数
Drop [temporary] function [if exists] [dbname.]function_name;
【注】如果创建的是临时的函数, 那么不需要删除, hive 关闭后就会自动失效;UDF 必须要有返回类型,可以返回 null,但是返回类型不能为 void
2.2 自定义 UDF 函数
2.2.1 创建一个Maven 工程;
2.2.2 导入依赖
<dependencies>
<!--https://mvnrepository.com/artifact/org.apache.hive/hive-exec -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>1.2.1</version>
</dependency>
</dependencies>
2.2.3 创建一个 Java 类
package com.atguigu.hive;
import org.apache.hadoop.hive.ql.exec.UDF;
/**
* @ author: cybeyond
* @ create: 2020-04-09-21:27
*/
public class MyUDF extends UDF {
public int evaluate(int data) {
return data + 5;
}
}
2.2.4 生成 jar 包, 并拷贝到服务器中 Hive 的 lib 下
使用 IDEA 的 Maven 工具将 package build 出来, 然后去 target 中将对应生成的 jar 包(我这的名称是 mr-1.0-SNAPSHOT-jar-with-dependencies.jar
)拷贝到 /opt/module/hive/lib
下;
【注】放在了 hive/lib
下之后, 重启 hive 就不需要再次添加 jar 包了;
2.2.5 添加 jar 包
hive (default)> add jar /opt/module/hive/lib/mr-1.0-SNAPSHOT-jar-with-dependencies.jar;
Added [/opt/module/hive/lib/mr-1.0-SNAPSHOT-jar-with-dependencies.jar] to class path
Added resources: [/opt/module/hive/lib/mr-1.0-SNAPSHOT-jar-with-dependencies.jar]
2.2.6 创建自定义函数
hive (default)> create function addFive as 'com.atguigu.hive.MyUDF';
OK
Time taken: 5.493 seconds
【注】as 后面的类名需要全限定类名;
2.2.7 使用 UDF 函数
hive (default)> select addFive(18);
OK
_c0
23
Time taken: 0.562 seconds, Fetched: 1 row(s)
2.3 自定义 UDTF 函数
自定义 UDTF 与 UDF 的区别是继承的类不同, UDTF 需要继承 GenericUDTF
类, 并重写其中的三个方法: initialize()
、 process()
和 close()
。
之后的打包、 上传到hive/lib
、 add jar
和创建函数都与自定义 UDF 一样;
2.3.1 创建一个类
package com.atguigu.hive.udtf;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import java.util.ArrayList;
import java.util.List;
/**
* @ author: cybeyond
* @ create: 2020-04-09-22:48
*/
public class MyUDTF extends GenericUDTF {
private List<String> dataList = new ArrayList<>();
@Override
public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
// 1. 定义【输出数据】的列名
List<String> fieldsNames = new ArrayList<>();
fieldsNames.add("word");
// 2. 定义【输出数据】的类型
List<ObjectInspector> fieldOIs = new ArrayList<>();
fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
return ObjectInspectorFactory.getStandardStructObjectInspector(fieldsNames, fieldOIs);
}
@Override
public void process(Object[] objects) throws HiveException {
// 1. 获取数据
String data = objects[0].toString();
// 2. 获取分隔符
String splitKey = objects[1].toString();
// 3. 切分数据
String[] words = data.split(splitKey);
// 4. 遍历写出
for (String word : words) {
// 5. 将数据放至集合
dataList.clear();
dataList.add(word);
// 6. 写出数据的操作
forward(dataList);
}
}
@Override
public void close() throws HiveException {
}
}
2.3.2 打包上传服务器
2.3.3 添加 jar 包
hive (default)> add jay /opt/module/hive/lib/mr-1.0-SNAPSHOT-jar-with-dependencies.jar;
Usage: add [FILE|JAR|ARCHIVE] <value> [<value>]*
Query returned non-zero code: 1, cause: null
2.3.4 创建自定义函数
hive (default)> create temporary function splitWords as 'com.atguigu.hive.udtf.MyUDTF';
OK
Time taken: 0.09 seconds
2.3.5 使用 UDTF 函数
hive (default)> select splitWords('hello-world-my-love', '-');
OK
word
hello
world
my
love
Time taken: 0.681 seconds, Fetched: 4 row(s)