hive学习笔记之十一:UDTF

这篇具有很好参考价值的文章主要介绍了hive学习笔记之十一:UDTF。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

为了验证UDTF的功能,咱们要先把表和数据都准备好:

  1. 新建名为t16的表:

create table t16(

person_name string,

string_field string

)

row format delimited

fields terminated by ‘|’

stored as textfile;

  1. 本地新建文本文件016.txt,内容如下:

tom|1:province:guangdong

jerry|2:city:shenzhen

john|3

  1. 导入数据:

load data

local inpath ‘/home/hadoop/temp/202010/25/016.txt’

overwrite into table t16;

  1. 数据准备完毕,开始编码;

UDTF开发的关键点

  1. 需要继承GenericUDTF类;

  2. 重写initialize方法,该方法的入参只有一个,类型是StructObjectInspector,从这里可以取得UDTF作用了几个字段,以及字段类型;

  3. initialize的返回值是StructObjectInspector类型,UDTF生成的每个列的名称和类型都设置到返回值中;

  4. 重写process方法,该方法中是一进多出的逻辑代码,把每个列的数据准备好放在数组中,执行一次forward方法,就是一行记录;

  5. close方法不是必须的,如果业务逻辑执行完毕,可以将释放资源的代码放在这里执行;

  6. 接下来,就按照上述关键点开发UDTF;

一列拆成多列

  • 接下来要开发的UDTF,名为udf_wordsplitsinglerow,作用是将入参拆分成多个列;

  • 下图红框中是t16表的一条原始记录的string_field字段,会被udf_wordsplitsinglerow处理:

hive学习笔记之十一:UDTF,程序员,hive,学习,笔记

  • 上面红框中的字段被UDTF处理处理后,一列变成了三列,每一列的名称如下图黄框所示,每一列的值如红框所示:

hive学习笔记之十一:UDTF,程序员,hive,学习,笔记

  • 以上就是咱们马上就要开发的功能;

  • 打开前文创建的hiveudf工程,新建WordSplitSingleRow.java:

package com.bolingcavalry.hiveudf.udtf;

import org.apache.commons.lang.StringUtils;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;

import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;

import org.apache.hadoop.hive.ql.metadata.HiveException;

import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;

import org.apache.hadoop.hive.serde2.objectinspector.*;

import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category;

import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

import java.util.ArrayList;

import java.util.List;

/**

  • @Description: 把指定字段拆成多列

  • @author: willzhao E-mail: zq2599@gmail.com

  • @date: 2020/11/5 14:43

*/

public class WordSplitSingleRow extends GenericUDTF {

private PrimitiveObjectInspector stringOI = null;

private final static String[] EMPTY_ARRAY = {“NULL”, “NULL”, “NULL”};

/**

  • 一列拆成多列的逻辑在此

  • @param args

  • @throws HiveException

*/

@Override

public void process(Object[] args) throws HiveException {

String input = stringOI.getPrimitiveJavaObject(args[0]).toString();

// 无效字符串

if(StringUtils.isBlank(input)) {

forward(EMPTY_ARRAY);

} else {

// 分割字符串

String[] array = input.split(“:”);

// 如果字符串数组不合法,就返回原始字符串和错误提示

if(null==array || array.length<3) {

String[] errRlt = new String[3];

errRlt[0] = input;

errRlt[1] = “can not split to valid array”;

errRlt[2] = “-”;

forward(errRlt);

} else {

forward(array);

}

}

}

/**

  • 释放资源在此执行,本例没有资源需要释放

  • @throws HiveException

*/

@Override

public void close() throws HiveException {

}

@Override

public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {

List<? extends StructField> inputFields = argOIs.getAllStructFieldRefs();

// 当前UDTF只处理一个参数,在此判断传入的是不是一个参数

if (1 != inputFields.size()) {

throw new UDFArgumentLengthException(“ExplodeMap takes only one argument”);

}

// 此UDTF只处理字符串类型

if(!Category.PRIMITIVE.equals(inputFields.get(0).getFieldObjectInspector().getCategory())) {

throw new UDFArgumentException(“ExplodeMap takes string as a parameter”);

}

stringOI = (PrimitiveObjectInspector)inputFields.get(0).getFieldObjectInspector();

//列名集合

ArrayList fieldNames = new ArrayList();

//列对应的value值

ArrayList fieldOIs = new ArrayList();

// 第一列的列名

fieldNames.add(“id”);

// 第一列的inspector类型为string型

fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);

// 第二列的列名

fieldNames.add(“key”);

// 第二列的inspector类型为string型

fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);

// 第三列的列名

fieldNames.add(“value”);

// 第三列的inspector类型为string型

fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);

return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);

}

}

  • 上述代码中的重点是process方法,取得入参后用冒号分割字符串,得到数组,再调用forward方法,就生成了一行记录,该记录有三列;

验证UDTF

接下来将WordSplitSingleRow.java部署成临时函数并验证;

  1. 编码完成后,在pom.xml所在目录执行命令mvn clean package -U;

  2. 在target目录得到文件hiveudf-1.0-SNAPSHOT.jar

  3. 将jar下载到hive服务器,我这里放在此目录:/home/hadoop/udf/

  4. 在hive会话模式执行以下命令添加本地jar:

add jar /home/hadoop/udf/hiveudf-1.0-SNAPSHOT.jar;

  1. 部署临时函数:

create temporary function udf_wordsplitsinglerow as ‘com.bolingcavalry.hiveudf.udtf.WordSplitSingleRow’;

  1. 执行以下SQL验证:

select udf_wordsplitsinglerow(string_field) from t16;

  1. 结果如下,可见每一行记录的string_field字段都被分割成了id、key、value三个字段:

hive> select udf_wordsplitsinglerow(string_field) from t16;

OK

id key value

1 province guangdong

2 city shenzhen

3 can not split to valid array -

Time taken: 0.066 seconds, Fetched: 3 row(s)

关键点要注意

  • 值得注意的是,UDTF不能和其他字段同时出现在select语句中,例如以下的SQL会执行失败:

select person_name,udf_wordsplitsinglerow(string_field) from t16;

  • 错误信息如下:

hive> select person_name,udf_wordsplitsinglerow(string_field) from t16;

FAILED: SemanticException [Error 10081]: UDTF’s are not supported outside the SELECT clause, nor nested in expressions

  • 如果希望得到UDTF和其他字段的结果,可以使用LATERAL VIEW语法,完整SQL如下:

select t.person_name, udtf_id, udtf_key, udtf_value

from (

select person_name, string_field

from t16

) t LATERAL VIEW udf_wordsplitsinglerow(t.string_field) v as udtf_id, udtf_key, udtf_value;

  • 查询结果如下,可见指定字段和UDTF都能显示:

hive> select t.person_name, udtf_id, udtf_key, udtf_value

from (

select person_name, string_field 
from  t16

) t LATERAL VIEW udf_wordsplitsinglerow(t.string_field) v as udtf_id, udtf_key, udtf_value;

OK

t.person_name udtf_id udtf_key udtf_value

tom 1 province guangdong

jerry 2 city shenzhen

john 3 can not split to valid array -

Time taken: 0.122 seconds, Fetched: 3 row(s)

一列拆成多行(每行多列)

  • 前面咱们试过了将string_field字段拆分成id、key、value三个字段,不过拆分后总行数还是不变,接下来的UDTF,是把string_field拆分成多条记录,然后每条记录都有三个字段;

  • 需要导入新的数据到t16表,新建文本文件016_multi.txt,内容如下:

tom|1:province:guangdong,4:city:yangjiang

jerry|2:city:shenzhen

john|3

  • 在hive会话窗口执行以下命令,会用016_multi.txt的内容覆盖t16表已有内容:

load data

local inpath ‘/home/hadoop/temp/202010/25/016_multi.txt’

overwrite into table t16;

  • 此时的数据如下图所示,红框中是一条记录的string_field字段值,咱们接下来要开发的UDTF,会先用逗号分隔,得到的就是1:province:guangdong和4:city:yangjiang这两个字符串,接下来对每个字符串用冒号分隔,就会得到两条id、key、value这样的记录,也就是多行多列:

hive学习笔记之十一:UDTF,程序员,hive,学习,笔记

  • 预期中的UDTF结果如下图所示,红框和黄框这两条记录都来自一条记录的string_field字段值:

hive学习笔记之十一:UDTF,程序员,hive,学习,笔记

  • 接下来开始编码,新建WordSplitMultiRow.java,代码如下,可见和WordSplitSingleRow的差异仅在process方法,WordSplitMultiRow的process中执行了多次forward,因此有了多条记录:

package com.bolingcavalry.hiveudf.udtf;

import org.apache.commons.lang.StringUtils;

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;

import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;

import org.apache.hadoop.hive.ql.metadata.HiveException;

import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;

import org.apache.hadoop.hive.serde2.objectinspector.*;

import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector.Category;

import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;

import java.util.ArrayList;

import java.util.List;

/**

  • @Description: 把指定字段拆成多行,每行有多列

  • @author: willzhao E-mail: zq2599@gmail.com

  • @date: 2020/11/5 14:43

*/

public class WordSplitMultiRow extends GenericUDTF {

private PrimitiveObjectInspector stringOI = null;

private final static String[] EMPTY_ARRAY = {“NULL”, “NULL”, “NULL”};

/**

  • 一列拆成多列的逻辑在此

  • @param args

  • @throws HiveException

*/

@Override

public void process(Object[] args) throws HiveException {

String input = stringOI.getPrimitiveJavaObject(args[0]).toString();

// 无效字符串

if(StringUtils.isBlank(input)) {

forward(EMPTY_ARRAY);

} else {

// 用逗号分隔

String[] rowArray = input.split(“,”);

// 处理异常

if(null==rowArray || rowArray.length<1) {

String[] errRlt = new String[3];

errRlt[0] = input;

errRlt[1] = “can not split to valid row array”;

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。hive学习笔记之十一:UDTF,程序员,hive,学习,笔记

hive学习笔记之十一:UDTF,程序员,hive,学习,笔记

hive学习笔记之十一:UDTF,程序员,hive,学习,笔记

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(资料价值较高,非无偿)

hive学习笔记之十一:UDTF,程序员,hive,学习,笔记

最后

这份《“java高分面试指南”-25分类227页1000+题50w+字解析》同样可分享给有需要的朋友,感兴趣的伙伴们可挑战一下自我,在不看答案解析的情况,测试测试自己的解题水平,这样也能达到事半功倍的效果!(好东西要大家一起看才香)

hive学习笔记之十一:UDTF,程序员,hive,学习,笔记

hive学习笔记之十一:UDTF,程序员,hive,学习,笔记

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
028)]

[外链图片转存中…(img-Qzjdx1zJ-1711617937028)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(资料价值较高,非无偿)

hive学习笔记之十一:UDTF,程序员,hive,学习,笔记

最后

这份《“java高分面试指南”-25分类227页1000+题50w+字解析》同样可分享给有需要的朋友,感兴趣的伙伴们可挑战一下自我,在不看答案解析的情况,测试测试自己的解题水平,这样也能达到事半功倍的效果!(好东西要大家一起看才香)

[外链图片转存中…(img-IWVnV2rO-1711617937029)]

[外链图片转存中…(img-JQt0JsBs-1711617937029)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!文章来源地址https://www.toymoban.com/news/detail-844541.html

到了这里,关于hive学习笔记之十一:UDTF的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 学习笔记-微服务高级(黑马程序员)

    测试软件 jmeter 雪崩问题 个微服务往往依赖于多个其它微服务,服务提供者I发生了故障,依赖于当前服务的其它服务随着时间的推移形成级联失败 超时处理 设定超时时间,请求超过一定时间没有响应就返回错误信息 仓壁模式 限定每个业务能使用的线程数,避免耗尽整个tom

    2024年04月25日
    浏览(54)
  • [学习笔记]黑马程序员python教程

    1.9.1异常的捕获 1.9.1.1 为什么要捕获异常 1.9.1.2 捕获常规的异常 1.9.1.3 捕获指定的异常 e是接受异常信息的变量 1.9.1.4 捕获多个异常 1.9.1.5 捕获全部异常 1.9.1.6 异常的else 1.9.1.7 异常的finally 1.9.2 异常的传递 如果异常是在某一层产生,但是没有被catch,那么会继续往上层抛出,此

    2024年02月07日
    浏览(71)
  • 【学习笔记】黑马程序员Java课程学习笔记(更新至第12章---集合)

    Java语言是美国Sun公司(Stanford University Network)在1995年推出的计算机语言, 2009年Oracle甲骨文公司收购Sun公司。Java之父:詹姆斯·高斯林(James Gosling)。 Java可以在任意操作系统上运行,Windows、Mac、Linux。我们只需要在运行Java应用程序的操作系统上,安装一个与操作系统对应

    2024年02月07日
    浏览(47)
  • 读程序员的README笔记01_学习如何学习

    6.3.2.1. 错误是不可避免的。成为一名软件工程师的路途艰辛,我们有时会失败 6.5.4.1. 代码从不说谎。注释有时却会。 6.5.4.1.1. Code never lies. Comments sometimes do 6.5.4.1.2. 去读源代码,因为它并不总是与设计文档相吻合 6.5.4.1.3. 不要只读你自己的代码库,还要去阅读高质量的开

    2024年02月05日
    浏览(51)
  • Linux命令基础,黑马程序员学习笔记

    command [-options] [parameter] command:命令本身 -options:[可选,非必填]命令的一些选项,可以通过选项控制命令的行为细节 parameter:[可选,非必填]命令的参数,多数用于命令的指向目标等 示例: ls -l /home/itheima ls是命令本身,-l是选项, /home/itheima是参数意思是以列表的形式,显示/home

    2024年02月19日
    浏览(97)
  • 【软考程序员学习笔记】——软件工程

      目录 🍊一、软件存周期 🍊二、软件生存周期模型 🍊三、软件开发方法 🍊四、需求分析 🍊五、内聚和耦合 🍉模块内的独立性--内聚性 🍉模块间的独立性--耦合性 🍊六、软件测试 🍉黑盒测试 🍉白盒测试 🍊七、V模型 🍊八、软件维护 🍊九、软件质量模型 问题定义

    2024年02月12日
    浏览(53)
  • [学习笔记]黑马程序员-Hadoop入门视频教程

    黑马程序员大数据Hadoop入门视频教程,适合零基础自学的大数据Hadoop教程 学习目标 1.理解大数据基本概念 2.掌握数据分析基本步骤 3.理解分布式、集群概念 4.学会VMware虚拟机的导入与使用 5.掌握Linux常用操作命令使用 6.掌握vi/vim编辑器基础使用 1.1.1 企业数据分析方向 数据分

    2024年02月13日
    浏览(54)
  • 黑马程序员 Java设计模式学习笔记(一)

    目录 一、设计模式概述 1.1、23种设计模式有哪些? 1.2、软件设计模式的概念 1.3、学习设计模式的必要性 1.4、设计模式分类 二、UML图 2.1、类图概述 2.2、类图的作用 2.3、类图表示法 类的表示方式 类与类之间关系的表示方式 关联关系 聚合关系 组合关系 依赖关系 继承关系

    2024年01月19日
    浏览(52)
  • 黑马程序员--分布式搜索ElasticSearch学习笔记

    黑马视频地址:https://www.bilibili.com/video/BV1LQ4y127n4/ 想获得最佳的阅读体验,请移步至我的个人博客 SpringCloud学习笔记 消息队列MQ学习笔记 Docker学习笔记 分布式搜索ElasticSearch学习笔记 ElasticSearch的作用 ElasticSearch 是一款非常强大的开源搜素引擎,具备非常强大的功能,可以帮

    2024年02月04日
    浏览(47)
  • 黑马程序员Docker快速入门到项目部署(学习笔记)

    目录 一、Docker简介 二、安装Docker 2.1、卸载旧版 2.2、配置Docker的yum库 2.3、安装Docker 2.4、启动和校验 2.5、配置镜像加速 2.5.1、注册阿里云账号 2.5.2、开通镜像服务 2.5.3、配置镜像加速 三、快速入门 3.1、部署MYSQL 3.2、命令解读 四、Docker基础 4.1、常见命令 4.1.1、命令介绍 4.1

    2024年01月25日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包