Hive自定义GenericUDTF函数官网示例
原文翻译:可以通过扩展
GenericUDTF
抽象类并实现initialize
、process
以及可能的close
方法来创建自定义UDTF
。initialize
方法由Hive调用,通知UDTF
应该期望的参数类型。然后,UDTF
必须返回一个对象检查器,对应于UDTF
将生成的行对象。一旦调用了initialize()
,Hive将使用process()
方法将行传递给UDTF
。在process()
中,UDTF可以通过调用forward()
生成并转发行给其他操作符。最后,当所有行都传递给UDTF
时,Hive将调用close()
方法。
官方示例代码:
/**
* GenericUDTFCount2输出已见行数的两倍。它被输出两次,以测试在关闭时使用lateral view输出行。
*/
public class GenericUDTFCount2 extends GenericUDTF {
Integer count = Integer.valueOf(0); // 初始化计数器为0
Object forwardObj[] = new Object[1]; // 创建一个用于forward的对象数组
// 关闭方法,在所有行传递给UDTF后调用
@Override
public void close() throws HiveException {
forwardObj[0] = count; // 将计数值放入forwardObj数组
forward(forwardObj); // 转发计数值
forward(forwardObj); // 再次转发计数值
}
// 初始化方法,用于设置输入参数的元数据信息
@Override
public StructObjectInspector initialize(ObjectInspector[] argOIs) throws UDFArgumentException {
ArrayList<String> fieldNames = new ArrayList<String>();
ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();
fieldNames.add("col1"); // 添加输出字段名
fieldOIs.add(PrimitiveObjectInspectorFactory.javaIntObjectInspector); // 添加输出字段类型
return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs); // 返回结构化对象检查器
}
// 处理方法,对每行数据进行处理
@Override
public void process(Object[] args) throws HiveException {
count = Integer.valueOf(count.intValue() + 1); // 计数器加一
}
}
这段代码实现了一个简单的UDTF,用于计算输入行的数量,并在关闭时输出两次计数值。初始化方法设置了输出字段的元数据信息,处理方法对每行数据进行计数操作。
下面是建表模拟测试数据后的结果:
1. 模拟数据测试函数udtf_count2
-- 创建student_scores表
CREATE TABLE student_scores
(
id INT,
name STRING,
score INT,
group_name STRING
);
INSERT OVERWRITE TABLE student_scores
VALUES (1, 'Jack', 96, 'A组'),
(2, 'John', 90, 'A组'),
(5, 'Lucy', 97, 'A组'),
(4, 'Caocao', 96, 'B组'),
(3, 'Lvbu', 99, 'B组');
-- 加载函数udtf_count2
ADD JAR /opt/jar/GenericUDTFCount2.jar;
CREATE TEMPORARY FUNCTION udtf_count2 AS 'com.xxx.GenericUDTFCount2';
-- 测试函数udtf_count2
SELECT id, name, score, group_name, a
FROM student_scores LATERAL VIEW udtf_count2(id) t AS a;
-- 执行结果:
| id | name | score | group_name | a |
|----|--------|-------|------------|---|
| 3 | Lvbu | 99 | B组 | 5 |
| 3 | Lvbu | 99 | B组 | 5 |
2. 重建分区表后测试函数udtf_count2
-- 重新创建student_scores分区表
DROP TABLE student_scores;
CREATE TABLE student_scores
(
id INT,
name STRING,
score INT,
group_name STRING
) PARTITIONED BY (dt STRING);
INSERT OVERWRITE TABLE student_scores PARTITION (dt = '20240320')
VALUES (1, 'Jack', 96, 'A组'),
(2, 'John', 90, 'A组'),
(5, 'Lucy', 97, ' A组');
INSERT OVERWRITE TABLE student_scores PARTITION (dt = '20240321')
VALUES (4, 'Caocao', 96, 'B组'),
(3, 'Lvbu', 99, 'B组');
-- 测试函数udtf_count2
SELECT id, name, score, group_name, a
FROM student_scores LATERAL VIEW udtf_count2(id) t AS a;
-- 执行结果:
| id | name | score | group_name | a |
|----|--------|-------|------------|---|
| 5 | Lucy | 97 | A组 | 3 |
| 5 | Lucy | 97 | A组 | 3 |
| 3 | Lvbu | 99 | B组 | 2 |
| 3 | Lvbu | 99 | B组 | 2 |