(33)创建 UDTF 函数——编写代码

本文介绍了如何在Maven工程中创建并实现一个Hive UDTF (User Defined Table Function)函数,用于解析JSONArray。步骤包括创建包、添加依赖、编写ExplodeJSONArray类,并将其打包上传到HDFS,最后在Hive中注册和使用这个函数。通过JSON数据拆分,提升数据处理效率。
摘要由CSDN通过智能技术生成
1 )创建一个 maven 工程: hivefunction
2 )创建包名: com.atguigu.hive.udtf
3 )引入如下依赖
<dependencies>
<!-- 添加 hive 依赖 -->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>3.1.2</version>
</dependency>
</dependencies>
4 )编码
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.ObjectInspectorF
actory;
import
org.apache.hadoop.hive.serde2.objectinspector.StructObjectInsp
ector;
import
org.apache.hadoop.hive.serde2.objectinspector.primitive.Primit
iveObjectInspectorFactory;
import org.json.JSONArray;
import java.util.ArrayList;
import java.util.List;
public class ExplodeJSONArray extends GenericUDTF {
@Override
public StructObjectInspector
initialize(StructObjectInspector argOIs) throws
UDFArgumentException {
// 1 参数合法性检查
if (argOIs.getAllStructFieldRefs().size() != 1){
throw new UDFArgumentException("ExplodeJSONArray 只需
要一个参数 ");
}
// 2 第一个参数必须为 string
if(!"string".equals(argOIs.getAllStructFieldRefs().get(0).getF
ieldObjectInspector().getTypeName())){
throw new
UDFArgumentException("json_array_to_struct_array 的第 1 个参数应为
string 类型 ");
}
// 3 定义返回值名称和类型
List<String> fieldNames = new ArrayList<String>();
List<ObjectInspector> fieldOIs = new
ArrayList<ObjectInspector>();
fieldNames.add("items");
fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectI
nspector);
return
ObjectInspectorFactory.getStandardStructObjectInspector(fieldN
ames, fieldOIs);
}
public void process(Object[] objects) throws HiveException
{
// 1 获取传入的数据
String jsonArray = objects[0].toString();
// 2 string 转换为 json 数组
JSONArray actions = new JSONArray(jsonArray);
// 3 循环一次,取出数组中的一个 json ,并写出
for (int i = 0; i < actions.length(); i++) {
String[] result = new String[1];
result[0] = actions.getString(i);
forward(result);
}
}
public void close() throws HiveException {
}
}
4.创建函数
1 )打包
2 )将 hivefunction-1.0-SNAPSHOT.jar 上传到 hadoop102 /opt/module ,然后再将该
jar 包上传到 HDFS /user/hive/jars 路径下
[atguigu@hadoop102 module]$ hadoop fs -mkdir -p /user/hive/jars
[atguigu@hadoop102 module]$ hadoop fs -put hivefunction-1.0-
SNAPSHOT.jar /user/hive/jars
3 )创建永久函数与开发好的 java class 关联
hive (gmall)>
create function
explode_json_array
as
'com.atguigu.hive.udtf.ExplodeJSONArray' using jar
'hdfs://hadoop102:8020/user/hive/jars/hivefunction-1.0-
SNAPSHOT.jar';
4 )注意:如果修改了自定义函数重新生成 jar 包怎么处理?只需要替换 HDFS 路径
上的旧 jar 包,然后重启 Hive 客户端即可。
5 )数据导入
hive (gmall)>
SET hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFo
rmat;
insert overwrite table dwd_action_log partition(dt='2020-06-14')
select
get_json_object(line,'$.common.ar'),
get_json_object(line,'$.common.ba'),
get_json_object(line,'$.common.ch'),
get_json_object(line,'$.common.md'),
get_json_object(line,'$.common.mid'),
get_json_object(line,'$.common.os'),
get_json_object(line,'$.common.uid'),
get_json_object(line,'$.common.vc'),
get_json_object(line,'$.page.during_time'),
get_json_object(line,'$.page.item'),
get_json_object(line,'$.page.item_type'),
get_json_object(line,'$.page.last_page_id'),
get_json_object(line,'$.page.page_id'),
get_json_object(line,'$.page.sourceType'),
get_json_object(action,'$.action_id'),
get_json_object(action,'$.item'),
get_json_object(action,'$.item_type'),
get_json_object(action,'$.ts')
from ods_log
lateral view
explode_json_array(get_json_object(line,'$.actions')) tmp as
action
where dt='2020-06-14'
and get_json_object(line,'$.actions') is not null;
3 )查看数据
hive (gmall)>
select * from dwd_action_log where dt='2020-06-14' limit 2;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据开发工程师-宋权

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值