概述
Hive自定义函数UDF、UDTF
-
hive中已经自带一些函数,但数量有限,有时候需要自己定义函数,自定义函数分为一下三种:
- 1、UDF(User-Defined-Function)
一进一出
类似于:lower/upper/reverse - 2、UDAF(User-Defined Aggregation Function)
聚集函数,多进一出
类似于:count/max/min
3、UDTF(User-Defined Table-Generating Functions)
一进多出
如lateral view explode()
- 1、UDF(User-Defined-Function)
1.自定义UDF
- 需求字符串大小写转换
1.1依赖
<dependencies>
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.5</version>
</dependency>
</dependencies>
1.2代码实现
/**
* @ClassName Uppercase
* @Description //转大写测试
* 用于 Hive 的用户定义函数 (UDF)。
* 新的 UDF 类需要从这个 UDF 类继承(或从GenericUDF继承,它以更高的复杂性为代价提供了更多的灵活性)。
* 扩展此 UDF 的所有类的要求是:
* 实现一个或多个名为evaluate方法,这些方法将由 Hive 调用(可以通过设置自定义UDFMethodResolver来配置 Hive 解析要调用的方法的确切方式)。 以下是一些示例:
* public int evaluate();
* public int evaluate(int a);
* public double evaluate(int a, double b);
* public String evaluate(String a, int b, Text c);
* public Text evaluate(String a);
* public String evaluate(List<Integer> a); (请注意,Hive 数组在 Hive 中表示为Lists 。因此ARRAY<int>列将作为List<Integer>传入。)
* evaluate永远不应该是一个无效的方法。 但是,如果需要,它可以返回null 。
* 返回类型和方法参数可以是 Java 原语或相应的Writable类。
* 这个类的一个实例将被每个 JVM 实例化,并且不会被并发调用。
* @Author mengfd
* @Date 2021/11/22 15:27
**/
public class Uppercase extends UDF {
public Text evaluate(final Text s) {
if (null == s) {
return null;
}
//返回大写字母
return new Text(s.toString().toUpperCase());
}
}
1.3 函数使用
1.3.1 临时函数
- 向hive的客户端添加jar包
cd /export/server/hive-2.1.0/lib
mv user-defined-function-1.0-SNAPSHOT.jar my_uppercase.jar
- 连接hive,添加自定义临时函数
add jar /export/server/hive-2.1.0/lib/my_uppercase.jar;
-- 自定义临时函数
create temporary function my_upercase as 'com.dk.udf.Uppercase';
-- 使用函数
select my_upercase("abcDe");
1.3.2 永久函数
- 上传jar到HDFS中
# 在hdfd创建jar包存放的文件夹
hadoop fs -mkdir /hive_func
# 上传jar包
hadoop fs -put /export/server/hive-2.1.0/lib/my_uppercase.jar /hive_func
- 连接hive,添加自定义函数
# 创建永久函数
create function my_upercase2 as 'com.dk.udf.Uppercase'
using jar 'hdfs://node1:8020/hive_func/my_uppercase.jar';
# 使用
select my_upercase2("abcDe");
2. 自定义UDTF
- 需求字符串一进多出
2.1 单列一进多出转换
2.1.1 代码实现
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;
/**
* @ClassName SplitString
* @Description UDTF 单列一进多出,
*
字符串拆分
*
参数1:需要拆分的数据
*
参数2:分隔符
* @Author mengfd
* @Date 2021/11/22 16:57
**/
public class SplitString extends GenericUDTF {
/** 初始化输出的字段 */
private final transient Object[] forwardList = new Object[1];
/**
* 初始化字段和检查器方法
* @param argOIs
* @return
* @throws UDFArgumentException
*/
@Override
public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
//初始化字段列表
List<String> fieldNames = new ArrayList<>();
fieldNames.add("column_1");
//初始化字段检查器列表,用于检查字段类型
List<ObjectInspector> inspectors = new ArrayList<>();
//设置第一个字段类型为string
inspectors.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, inspectors);
}
@Override
public void process(Object[] args) throws HiveException {
if (args == null || args.length < 1){
super.forward(forwardList);
return;
}
//获取需要拆分的数据
String argsStr = args[0].toString();
//获取字段分隔符
String splitStr = args[1].toString();
//获取拆分后的数组
String[] fields = argsStr.split(splitStr);
for (String field : fields) {
//放入输出字段集合
forwardList[0] = field;
//输出
super.forward(forwardList);
}
}
@Override
public void close() throws HiveException {
}
}
2.1.2 函数使用
add jar /export/server/hive-2.1.0/lib/my_split_string.jar;
create temporary function split_string_udtf as 'com.dk.udtf.SplitString';
select split_string_udtf("索隆,路飞,山治,乔巴", ",");
2.2 多列一进多出转换
2.2.1 代码实现
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.Arrays;
import java.util.List;
/**
* @ClassName SplitMapList
* @Description UDTF一进多出,多列
*
入参:
*
参数1:需要拆分的数据,“路飞:12000000000,索隆:8000000000,乔巴:3000000”
* @Author mengfd
* @Date 2021/11/22 18:39
**/
public class SplitMapList<main> extends GenericUDTF {
/**初始化一个长度为2的输出列表*/
private final transient Object[] fieldlist = new Object[2];
@Override
public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
//初始化列名
List<String> fieldList = new ArrayList<>();
fieldList.add("column_1");
fieldList.add("column_2");
//初始化字段检查器,分别对应上面两个输出列的类型
List<ObjectInspector> inspectors = new ArrayList<>();
inspectors.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
inspectors.add(PrimitiveObjectInspectorFactory.javaLongObjectInspector);
//返回列名和字段检查器集合
return ObjectInspectorFactory.getStandardStructObjectInspector(fieldList, inspectors);
}
@Override
public void process(Object[] args) throws HiveException {
if (args == null || args.length < 1){
super.forward(fieldlist);
return;
}
//arg0需要分析的数据
String arg0 = args[0].toString();
//arg1第一个分隔符
String arg1 = args[1].toString();
//arg2第二个分隔符
String arg2 = args[2].toString();
String[] items = arg0.split(arg1);
for (String item : items) {
String[] beans = item.split(arg2);
fieldlist[0] = beans[0];
fieldlist[1] = Long.parseLong(beans[1]);
//
fieldlist[1] = beans[1];
super.forward(fieldlist);
}
}
@Override
public void close() throws HiveException {
}
public static void main(String[] args) {
String[] strings = new String[3];
strings[0] = "路飞:12000000000,索隆:8000000000,乔巴:3000000";
strings[1] = ",";
strings[2] = ":";
//arg0需要分析的数据
String arg0 = strings[0].toString();
//arg1第一个分隔符
String arg1 = strings[1].toString();
//arg2第二个分隔符
String arg2 = strings[2].toString();
String[] items = arg0.split(arg1);
for (String item : items) {
String[] beans = item.split(arg2);
System.out.println(Arrays.toString(beans));
}
}
}
2.2.2 函数使用
-- mv user-defined-function-1.0-SNAPSHOT.jar my_split_map.jar
drop function my_split_map;
create function my_split_map as 'com.dk.udtf.SplitMapList'
using jar 'hdfs://node1:8020/hive_func/my_split_map.jar';
select my_split_map("路飞:12000000000,索隆:8000000000,乔巴:3000000", ",", ":");
2.3 删除函数命令
-- 删除临时函数
drop temporary function if exists encryptPhoneNumber;
-- 删除永久函数,不会删除HDFS上的jar包
drop function if exists my_lower2;
最后
以上就是可靠棉花糖为你收集整理的Hive自定义函数UDF、UDTFHive自定义函数UDF、UDTF的全部内容,希望文章能够帮你解决Hive自定义函数UDF、UDTFHive自定义函数UDF、UDTF所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复