hive的自定义函数

一、自定义函数的实现方式

1.创建临时函数

   (1)创建maven项目,并加入依赖

<dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-exec</artifactId>
            <version>3.1.2</version>
        </dependency>

  (2)编写函数的实现逻辑的代码

(3)打成jar包并上传至Linux虚拟机(带依赖打包)

(4)在hive shell中,使用 add jar 路径将jar包作为资源添加到hive环境中

        add jar jar包路径;

(5)使用jar包资源注册一个临时函数,fxxx1是函数名,'MyUDF'是主类名

        create temporary function fxxx1 as 'MyUDF';

(6)可以使用show functions 查看函数是否被创建

2.创建永久函数

(1)将jar上传HDFS:

          hadoop fs -put jar包路径

(2)在hive命令行中创建永久函数:

         create function 函数名 as '主类名路径' using jar 'hdfs:/bigdata29/jars/hive-1.0-jar-with-dependencies.jar(hdfs上的jar包路径)';

(3)删除永久函数

         drop function 函数名;

3.实现UDF自定义函数

(旧版本方式):

import org.apache.hadoop.hive.ql.exec.UDF;/*旧版本实现UDF自定义函数的时候,需要将自己的类继承UDF类*/
public class MyUDFDemo1 extends UDF {/*实现evaluate函数将来hive调用自定义函数的时候,实际上调用的是该类中的evaluate函数evaluate函数的参数就是将来sql语句传入的列值evaluate函数的返回值就是自定义函数的返回值需求:传入一个字符串,返回一个新的字符串举例:SMITH --> 数加:SMITHselect xxx(ename) from emp;*/public String evaluate(String str) {// 返回字符串前缀"数加:"加上输入参数strreturn "数加:" + str;}public String evaluate(int number) {// 返回字符串前缀"数加:"加上输入参数strif(number>=90 && number<=100){return "优秀";}else if(number>=70 && number<90){return "良好";}else if(number>=60){return "及格";}else {return "不及格";}}}

(新版本方式):

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;public class MyGenericUDFDemo1 extends GenericUDF {/*这个方法主要是对自定义的UDF函数进行初始化,目的是指定调用完函数返回的值的类型需求:传入一个字符串,返回一个新的字符串举例:SMITH --> 数加:SMITH*/@Overridepublic ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {//使用PrimitiveObjectInspectorFactory工厂类,获取String类型的ObjectInspectorreturn PrimitiveObjectInspectorFactory.javaStringObjectInspector;}/*该方法是自定义UDF的核心方法,目的是实现自定义UDF的逻辑是在initialize方法之后执行的arguments将来会有多个参数,但是UDF函数只有一个参数,所以arguments[0]就是传入的第一个参数*/@Overridepublic Object evaluate(DeferredObject[] arguments) throws HiveException { //xiaohu("smith")  xiaohu(60)String output = ""; //arguments[0]获取第一个参数值,通过get()方法获取其中的参数具体值Object o = arguments[0].get(); // Object o = 100if (o != null) { //如果将来调用自定义函数不传值的话,则o为null,需要加入判断,防止空指针异常if (o instanceof Text) {output = "数加:" + o;}else if(o instanceof IntWritable){ // hive中传入整数的时候,底层默认是IntWritable类型的int score = ((IntWritable) o).get();if(score>=90 && score<=100){output = "优秀";}else if(score>=70 && score<90){output = "良好";}else if(score>=60){output = "及格";}else {output = "不及格";}}}return output;}@Overridepublic String getDisplayString(String[] children) {return "这是我们自己使用新版本写法自定义的UDF函数";}
}

4.实现UDTF自定义函数

案例1:

将一行数据  M1001#xiaohu#S324231212,lkd#M1002#S2543412432,S21312312412#M1003#bfy

变为以下形式(三行):

1001 xiaohu 324231212

1002 lkd 2543412432

1003 bfy 21312312412

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;/*编写UDTF的类需要自己自定义的类继承自GenericUDTF*/
public class MyUDTFDemo1 extends GenericUDTF {/*public StructObjectInspector initialize(StructObjectInspector argOIs)指定输出的列的名称以及列的类型M1001#xiaohu#S324231212,sp#M1002#S2543412432,S21312312412#M1003#dyj1001 xiaohu 324231212*/@Overridepublic StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {//创建一个List集合存储结果列的名字ArrayList<String> colNames = new ArrayList<>();//创建一个集合存储每一列的数据类型ArrayList<ObjectInspector> colTypes = new ArrayList<>();//向集合中添加元素,设置列的名字以及类型colNames.add("id");colTypes.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);colNames.add("name");colTypes.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);colNames.add("cardId");colTypes.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);//返回一个对象,该对象封装了列的名字以及列的类型return ObjectInspectorFactory.getStandardStructObjectInspector(colNames, colTypes);}/*process方法主要是在调用函数的时候,底层会进行调用处理传入的列数据M1001#xiaohu#S324231212,sp#M1002#S2543412432,S21312312412#M1003#dyjargs: 接收函数调用时传入的列数据,从索引0开始*/@Overridepublic void process(Object[] args) throws HiveException {//创建一个数组,存储每一列的数据//因为结果一行数据中有3列,需要创建一个长度为3的数组,用来存储我们处理过的一行三列数据String[] rows = new String[3];//args[0]是传入的第一个列数据String col = args[0].toString();String[] infos = col.split(",");//遍历切分后的数组,得到每一个用户信息for (String info : infos) {String[] strings = info.split("#");for (String i : strings) {if(i.startsWith("M")){ // M1001rows[0] = i.substring(1);}else if(i.startsWith("S")){rows[2] = i.substring(1);}else {rows[1] = i;}}//forward(Object o) 调用概述方法,将输出的一行数据,封装成一个数组,传入到forward方法中,给hive后续处理forward(rows);}}@Overridepublic void close() throws HiveException {//这里一般是用作释放在initialize方法中创建的资源}
}

案例二:

字段:id,col1,col2,col3,col4,col5,col6,col7,col8,col9,col10,col11,col12 共13列

数据:

a,1,2,3,4,5,6,7,8,9,10,11,12

b,11,12,13,14,15,16,17,18,19,20,21,22

c,21,22,23,24,25,26,27,28,29,30,31,32

转成3列:id,hours,value

例如:

a,1,2,3,4,5,6,7,8,9,10,11,12

a,0时,1

a,2时,2

a,4时,3

a,6时,4

......

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;/*输入:a,1,2,3,4,5,6,7,8,9,10,11,12输出:a 0时 1a 2时 2a 4时 3..a 24时 12*/
public class MyUDTFDemo3 extends GenericUDTF {@Overridepublic StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {//创建一个List集合存储结果列的名字ArrayList<String> colNames = new ArrayList<>();//创建一个集合存储每一列的数据类型ArrayList<ObjectInspector> colTypes = new ArrayList<>();//向集合中添加元素,设置列的名字以及类型colNames.add("id");colTypes.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);colNames.add("time");colTypes.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);colNames.add("value");colTypes.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);//返回一个对象,该对象封装了列的名字以及列的类型return ObjectInspectorFactory.getStandardStructObjectInspector(colNames, colTypes);}/*输入:a,1,2,3,4,5,6,7,8,9,10,11,12输出:a 0时 1a 2时 2a 4时 3..a 24时 12*/@Overridepublic void process(Object[] args) throws HiveException { //作用在每一行上的//创建一个数组,存储一行三列的数据String[] rows = new String[3];//因为接收了13列的数据,args的长度是13 索引最大值是12//第一列是监测点编号String id = args[0].toString();rows[0] = id;for (int i = 1, j = 0; i < args.length; i++, j += 2) {rows[1] = j + "时";rows[2] = args[i].toString();forward(rows);}}@Overridepublic void close() throws HiveException {}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/812532.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

02-攻防世界PHP2

题目 authenticate:证明什么是真的 解题 观察题目可知&#xff0c;访问index.phps可能会有不一样的发现 http://61.147.171.105:51671/index.phps访问该链接&#xff0c;可以得到下面的界面 这里只显示出了部分代码&#xff0c;右键该界面&#xff0c;点击查看源代码&#xf…

使用ArrayList.removeAll(List list)导致的机器重启

背景 先说一下背景&#xff0c;博主所在的业务组有一个核心系统&#xff0c;需要同步两个不同数据源给过来的数据到redis中&#xff0c;但是每次同步之前需要过滤掉一部分数据&#xff0c;只存储剩下的数据。每次同步的数据与需要过滤掉的数据量级大概在0-100w的数据不等。 由…

Qt/QML编程之路:图片进度条的实现(50)

要实现进度条,而进度条是通过一个图片来展示的,比如逐渐增大的音量,或者逐步增大的车速,通过图片显示的效果肯定更好一些。最直接的想法是通过一个透明的rectagle,把不想让看到的遮住,实际上这种方法不可行。 import QtQuick 2.5 import QtQuick.Window 2.2 import QtGra…

【学习】移动端兼容性测试有什么方法及重要性

随着移动互联网的快速发展&#xff0c;移动应用程序已经成为人们日常生活中不可或缺的一部分。然而&#xff0c;由于各种移动设备的硬件和软件差异&#xff0c;移动应用程序的兼容性问题也越来越突出。因此&#xff0c;移动端兼容性测试成为了一个重要的环节&#xff0c;它可以…

如何在 Android 设备上恢复已删除/丢失的文档

随着Android设备内存容量的不断增加&#xff0c;许多人将手机作为移动硬盘来存储大量文档或其他文件。由于某些原因&#xff0c;文件丢失绝对是一场彻头彻尾的噩梦&#xff0c;因为里面的数据可能是要汇报的学习档案、领导会议的安排、或者付费电子书等。通常&#xff0c;你首先…

如何备考蓝桥杯赛事 怎样才能取得好成绩?

在计算机领域&#xff0c;蓝桥杯赛事一直是备受关注的比赛之一。参加蓝桥杯不仅可以锻炼自己的编程能力&#xff0c;还能够结识志同道合的朋友&#xff0c;拓展自己的人际关系。然而&#xff0c;想要在蓝桥杯赛事中取得好成绩并不是一件容易的事情&#xff0c;需要充分的准备和…

02_JavaWeb中的Tomcat(详解)

文章目录 Tomcat1, 概述1.1 安装1.2 目录结构1.3 启动/停止 2, 资源部署2.1 直接部署: 主要和重要的方式2.2 虚拟映射: 重要2.2.1 方式一:2.2.1 方式二: 2.3 原理解析 3, Tomcat组件3.1 Connector3.2 Engine3.2.1 Host3.2.1.1 Context 4, 其它: 重要4.1 设置 Tomcat 1, 概述 w…

sql server2008触发器

sql server在Navicat工具不能插入数据 可以去写代码插入&#xff0c;代码连接sql server可以插入 或者使用sql server专门的工具 BEGINdeclare a int;declare s t_amount;select a baddebt_age_id,srate from aa_baddebt_age;INSERT INTO dade(id,name) VALUES(a,s) END

手机外屏碎8折维修,天星金融(原小米金融)助阵米粉节

今年4月6日是小米公司14岁生日&#xff0c;也是一年一度的盛会“米粉节”。据“小米服务”官方公众号发布的消息&#xff0c;为庆祝这一重要日子&#xff0c;从4月6日起至4月17日&#xff0c;为用户带来一系列服务权益。 据悉&#xff0c;活动共包括8项服务权益&#xff0c;其…

2024年认证杯SPSSPRO杯数学建模B题(第一阶段)神经外科手术的定位与导航全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 B题 神经外科手术的定位与导航 原题再现&#xff1a; 人的大脑结构非常复杂&#xff0c;内部交织密布着神经和血管&#xff0c;所以在大脑内做手术具有非常高的精细和复杂程度。例如神经外科的肿瘤切除手术或血肿清除手术&#xff0c;通常需要…

12.4.1 实验1:配置CDP

12.4.1 实验1&#xff1a;配置CDP 1、实验目的 通过本实验可以掌握: CDP特征。CDP配置和调试方法。通过CDP查看设备直连邻居信息的方法。 2、实验拓扑 配置CDP的实验拓扑如上图所示。 3、实验步骤 &#xff08;1&#xff09;配置路由器R1 R1(config)#interface serial 0…

选择成为一名程序员:兴趣与职业发展的交织

在当今信息化、数字化的时代&#xff0c;程序员这一职业越来越受到年轻人的青睐。那么&#xff0c;是什么原因驱使他们选择走上编程这条道路呢&#xff1f;是纯粹的兴趣使然&#xff0c;还是对未来职业发展的深思熟虑&#xff1f;本文将深入探讨这一话题&#xff0c;分析兴趣与…

【opencv】示例-pca.cpp PCA图像重建演示

// 加载必要的头文件 #include <iostream> // 用于标准输入输出流 #include <fstream> // 用于文件的输入输出 #include <sstream> // 用于字符串的输入输出流操作#include <opencv2/core.hpp> // OpenCV核心功能的头文件 #include "o…

Pycharm通过配置隧道连接远程服务器

前言&#xff1a; 上篇有说到局域网windows和服务器互通的情况下连接远程pycharm&#xff0c;这次咱们来说下通过跳板机的方式连接服务器如何做到windows远程连接到服务器 1&#xff1a;设置SSH隧道或SSH代理 ssh -L localhost:LOCAL_PORT:FINAL_SERVER_IP:FINAL_SERVER_PORT…

Prompt编写——安全边界

在编写prompt&#xff08;提示、指令或引导语&#xff09;时&#xff0c;设置安全边界主要是为了防止生成的内容超出预期或包含不合适、有害的信息。特别是在使用大型语言模型时&#xff0c;如GPT系列模型&#xff0c;设置安全边界至关重要。以下是一些建议来设置安全边界&…

如何实现vue点击按钮进行图片浏览 ?

以下是官方的写法&#xff0c;并不能达到我们的要求&#xff0c;官方实现的功能是点击图片达到预览大图的效果。如果你的按钮就是图片&#xff0c;也可以达到目前的功能 <div class"demo-image__preview"><el-imagestyle"width: 100px; height: 100px…

AI赋能的BIM体验

近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术与建筑信息模型&#xff08;BIM&#xff09;的融合给建筑行业带来了革命性的变化。 BIM 是建筑物物理和功能特征的数字表示&#xff0c;与 AI 功能相结合&#xff0c;显着改变了客户的体验。 在本文中&#xff0c;我们…

搭建Android内核和Framework开发和调试环境

环境 ubuntu20.04或者22.04 x86_64 步骤 搭建cuttlefish运行环境 参考:搭建 Cuttlefish 运行环境 安装下面的软件包sudo apt install -y git devscripts config-package-dev debhelper-compat golang curl 其他,可以参考这个链接,安装android依赖的软件包: sudo apt i…

1.Chinese Tiny LLM_ Pretraining a Chinese-Centric Large Language Model

文章目录 摘要一、背景二、预训练数据统计信息数据处理 模型架构 三、SFT四、Learning from Human Preferences五、评估数据集和指标训练过程和比较分析安全性评估中文硬指令理解与遵循评价 六、结论 https://arxiv.org/abs/2404.04167https://github.com/Chinese-Tiny-LLM/Chi…

python 今日小知识1——parser

argparse模块&#xff0c;其实质就是将相关参数进行设置。相对专业说法&#xff1a; argparse 模块提供轻松编写用户友好的命令行接口。 程序定义它需要的参数&#xff0c;然后 argparse 将弄清如何从 sys.argv 解析出那些参数。 argparse 模块会自动生成帮助和使用手册&#…