Hive之扩展函数(UDF)

news2024/9/9 0:33:34

Hive之扩展函数(UDF)

1、概念讲解

当所提供的函数无法解决遇到的问题时,我们通常会进行自定义函数,即:扩展函数。Hive的扩展函数可分为三种:UDF,UDTF,UDAF

UDF:一进一出

UDTF:一进多出

UDAF:多进一出

2、UDF的基本实现

业务功能介绍

此处创建的UDF业务功能介绍:给定三个参数,参数一和参数二为日期,参数三为不同维度(年,季度,月,周,日)。根据不同维度计算两日期之间相差的值。

一:依赖

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

二:接口的定义

UDF基本接口定义
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;

import java.util.Objects;

//校验:若无法匹配,则抛异常
public interface UDFCom {
    //校验传参的数量与元素
    default void validateArgs(Object[] args,int size) throws UDFArgumentException {
        //校验 数量 是否为空
        if (size>0 && Objects.isNull(args) || args.length<size){
            throw new UDFArgumentException(size+"args must be provided");
        }
        //size 之内的元素进行验证
        for (int i=0 ;i < size ; i++){
            if (Objects.isNull(args[i])){
                throw new UDFArgumentException("type of args["+i+"] null");
            }
        }
    }

    //校验所有类型为基本类型
    default void validateAllPrimitiveArgs(Object[] args,int size) throws UDFArgumentException{
        for (int i = 0; i < size; i++) {
            // ObjectInspector: 解析并获取内部数据结构信息的工具
            // getCategory():提取类型
            // PRIMITIVE:基本类型
            if (((ObjectInspector)args[i]).getCategory() != ObjectInspector.Category.PRIMITIVE){
                throw new UDFArgumentException("only support primitive type");
            }
        }
    }
}
日期接口定义(业务需求)
import org.apache.hadoop.hive.ql.metadata.HiveException;

//校验:若无法匹配,则抛异常
public interface DateCom {
    //日期的格式验证
    default void validateDateFormat(String...dateStrArr) throws HiveException {
        for (String s : dateStrArr) {
            if (!s.matches("\\d{4}-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2][0-9]|3[0-1])")){
                throw new HiveException("date format illegal : " + s);
            }
        }
    }
}

三:方法的实现

package com.ybg.hive.ql.func.udf;

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.primitive.PrimitiveObjectInspectorFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Objects;

public class UDFDataDiffByUnit extends GenericUDF implements UDFCom, DateCom {
    //管理参数的【类型】 => 验证
    @Override
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        //验证
        validateArgs(arguments,2);// 验证参数数量及元素
        validateAllPrimitiveArgs(arguments,2);// 验证类型是否为基本类型
        return PrimitiveObjectInspectorFactory.javaStringObjectInspector;// 传进来参数为字符串
    }

    //管理参数的【值】 => 验证 + 业务
    @Override
    public Object evaluate(DeferredObject[] arguments) throws HiveException {
        /**
         * 验证
         */
        validateArgs(arguments,2);//验证数量
        /**
         * 业务功能
         */
        String strDateSmall = arguments[0].get().toString();//获取【参数一】的日期
        String strDateBig = arguments[1].get().toString();//获取【参数二】的日期
        //日期格式的验证
        validateDateFormat(strDateSmall,strDateBig);
        //比较日期大小:规定 前面日期 < 后面日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar dateSmall = Calendar.getInstance();
        Calendar dateBig = Calendar.getInstance();
        try {
            dateSmall.setTime(sdf.parse(strDateSmall));
            dateBig.setTime(sdf.parse(strDateBig));
        } catch (ParseException e) {
            throw new HiveException(e);
        }
        if (dateSmall.after(dateBig)){
            throw new HiveException("dateSmall by arg1 > dateBig by arg2");
        }
        //根据不同情况进行计算
        String unit = arguments[2].get().toString().toLowerCase();
        int intUnit = 0;
        switch (unit){
            case "y":// 2019-10-15  2020-8-15
                intUnit = Calendar.YEAR;
                break;
            case "q": case "m":
                intUnit = Calendar.MONTH;
                break;
            case "w": case "d":
                intUnit = Calendar.DATE;
                break;
            default:
                throw new HiveException("not support unit by arg3 : " + unit);
        }
        int diff = -1;
        while (true){
            diff++;
            dateSmall.add(intUnit,1);
            if (dateSmall.after(dateBig)) {
                //结束的标志
                break;
            }
        }
        switch (unit){
            case "q":
                diff/=3;
                break;
            case "w":
                diff/=7;
                break;
        }
        return diff;
    }

    @Override
    public String getDisplayString(String[] children) {
        return Objects.isNull(children) || children.length==0 || null == children[0] ? null : children[0];
    }
}

四:打jar包上传至HDFS

第一步:打执行jar包,选择选择 package 选项。

第二步:找到jar包的物理磁盘位置(右键点击jar包 => Open in => Explorer)
第三步:将jar包上传至HDFS

五:创建 hive udf 映射至hdfs jar包并指定主类

基本语法

全包路径:右键 => copy path => copy reference

create function fl_day as '继承了GenericUDF的全包路径'
using jar 'hdfs上的jar包的路径';

实际运用

-- 创建连接
create function uud as 'com.ybg.hive.ql.func.udf.UDFDataDiffByUnit'
using jar 'hdfs://single:9000/hive/udf/hiveudf-2.3.jar';
-- 测试
select uud('2018-8-15','2020-8-15',"q") as quarterDiff

六:后期更新函数

第一步:先删函数
	drop function if exists 函数名;
第二步:关闭连接
	File -> Close Project
第三步:重新注入
	create function uud as 'com.ybg.hive.ql.func.udf.UDFDataDiffByUnit'
	using jar 'hdfs://single:9000/hive/udf/hiveudf-1.0-SNAPSHOT.jar';

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

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

相关文章

YOLO v8目标检测(三)模型训练与正负样本匹配

YOLO v8目标检测 损失函数理论 在YOLO v5模型中&#xff0c;cls, reg, obj代表的是三个不同的预测组成部分&#xff0c;对应的损失函数如下&#xff1a; cls: 这代表类别预测&#xff08;classification&#xff09;。对应的损失是类别预测损失&#xff08;loss_cls&#xff…

Win10出现错误代码0x80004005 一键修复指南

对于 Windows 10 用户来说&#xff0c;错误代码 0x80004005 就是这样一种迷雾&#xff0c;它可能在不经意间出现&#xff0c;阻碍我们顺畅地使用电脑。这个错误通常与组件或元素的缺失有关&#xff0c;它可能源自注册表的错误、系统文件的损坏&#xff0c;或者是软件的不兼容。…

listener监听

背景: 过滤器代码也可实现接口请求次数统计,但会影响过滤器本意;故在dispatcher servlet层进行监听统计 价值: 所有接口的次数统计可适用于系统全天访问量; 单个请求接口的次数统计可在企业中根据接口次数的高低,可分析出接口对应的功能受用户的喜好程度 请求通过过滤器到了s…

common-intellisense:助力TinyVue 组件书写体验更丝滑

本文由体验技术团队Kagol原创~ 前两天&#xff0c;common-intellisense 开源项目的作者 Simon-He95 在 VueConf 2024 群里发了一个重磅消息&#xff1a; common-intellisense 支持 TinyVue 组件库啦&#xff01; common-intellisense 插件能够提供超级强大的智能提示功能&…

c生万物系列(职责链模式与if_else)

从处理器的角度来说&#xff0c;条件分支会导致指令流水线的中断&#xff0c;所以控制语句需要严格保存状态&#xff0c;因为处理器是很难直接进行逻辑判断的&#xff0c;有可能它会执行一段时间&#xff0c;发现出错后再返回&#xff0c;也有可能通过延时等手段完成控制流的正…

skynet 实操篇

文章目录 概述demo启动文件skynet_start配置文件main.luastart函数thread_workerskynet_context_message_dispatchskynet_mq_popdispatch_message 小结 概述 上一篇写完skynet入门篇&#xff0c;这一篇写点实操性质的。 demo 对于一个开源框架&#xff0c;大部分都有他们自己…

《Linux运维总结:基于x86_64架构CPU使用docker-compose一键离线部署zookeeper 3.8.4容器版分布式集群》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;《Linux运维篇&#xff1a;Linux系统运维指南》 一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面对不同的客户部署业务系统&#xff0…

C++客户端Qt开发——界面优化(美化登录界面)

美化登录界面 在.ui中拖入一个QFream&#xff0c;顶层窗口的QWidget无法设置背景图片&#xff0c;套上一层QFrame将背景图片设置到QFrame上即可 用布局管理器管理元素&#xff1a;用户名LineEdit&#xff0c;密码LineEdit&#xff0c;记住密码ComboBox&#xff0c;登录Button…

ubuntu2204安装elasticsearch7.17.22

下载安装 wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.22-amd64.deb wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.22-amd64.deb.sha512 shasum -a 512 -c elasticsearch-7.17.22-amd64.deb.sha512 su…

web、http协议、apache服务、nginx服务

web基本概念和常识 概念 web&#xff1a;为用户提供的一种在互联网上浏览信息的服务&#xff0c;是动态的、可交互的、跨平台的和图形化的&#xff1b; 为用户提供各种互联网服务&#xff0c;这些服务包括浏览服务以及各种交互式服务&#xff0c;包括聊天、购物等&#xff1…

windows下,pyrouge安装教程

1.安装perl 1.1 在命令行&#xff0c;检查perl是否安装 perl-v 1.2 安装perl 下载地址 Strawberry Perl for Windows - Releases 1&#xff09;下载msi版本 2&#xff09;双击安装包&#xff0c;傻瓜式安装&#xff0c;一路next&#xff0c;&#xff08;可修改安装路径&am…

Matlab编程资源库(16)数值微分

一、数值差分与差商 在Matlab中&#xff0c;数值差分与差商是数值分析中常用的概念&#xff0c;尤其在求解微分方程、插值、逼近等领域有广泛应用。下面简要介绍这两个概念及其在Matlab中的实现。 数值差分 数值差分是微分运算的离散化形式&#xff0c;用于近似求解导数。给定…

宠物浮毛空气净化器真的有用吗?性价比高的浮毛空气净化器推荐

作为一位5年资深铲屎官&#xff0c;随着养猫的家庭数量不断增加&#xff0c;轻松撸猫虽然很快乐。然而&#xff0c;宠物的存在也可能引发一些问题&#xff0c;比如宠物的体味和脱落的毛发&#xff0c;这些都可能成为影响家庭健康的隐患。特别是宠物排泄物的气味&#xff0c;如果…

C++11中的右值引用以及移动构造等

目录 一、右值引用 1.左值引用和右值引用 2.左值引用与右值引用比较 3.右值引用使用场景和意义 1️⃣ 传返回值 2️⃣ STL中的应用 4.完美转发 模板中的&& 万能引用&#xff08;引用折叠&#xff09; 二、 新的类功能 1.默认成员函数 2.类成员变量初始化 3.…

【找到字符串中所有字母异位词】python刷题记录

R2-滑动窗口篇 滑动窗口哈希表 和之前那道一样 http://t.csdnimg.cn/dpIbt class Solution:def findAnagrams(self, s: str, p: str) -> List[int]:#返回字典记录了每个字符出现的次数counter1collections.Counter(p)#滑动窗口记录counter2即可ret[]num2len(s)num1len(p…

VIM基础配置

1. CTAGS配置 下载 上传虚拟机&#xff0c;解压&#xff0c;进入目录 tar -xzvf ctags-5.8.tar.gz cd ctags-5.8/编译 ./configure sudo make sudo make install查看是否安装成功 ctags --version打印如下 2. 使用Vundle 下载 git clone https://github.com/VundleVim/Vund…

如何将WordPress文章中的外链图片批量导入到本地

在使用采集软件进行内容创作时&#xff0c;很多文章中的图片都是远程链接&#xff0c;这不仅会导致前端加载速度慢&#xff0c;还会在微信小程序和抖音小程序中添加各种域名&#xff0c;造成管理上的麻烦。特别是遇到没有备案的外链&#xff0c;更是让人头疼。因此&#xff0c;…

2024下《系统架构设计师》案例简答题,刷这些就够了!

2024年软考下半年已经越来越近了&#xff0c;不知道今年备考架构的同学们准备得怎么样了呢&#xff1f; 简答题一直是架构拿分的重点区域&#xff0c;对于许多考生来说&#xff0c;也往往是最具挑战性的部分。今天我就把那些重要的案例简答题类型整理汇总给大家&#xff0c;希望…

C++选择题带答案

1&#xff0e;下列关于定义一个指向double型变量的指针&#xff0c;正确的是&#xff08; B &#xff09;。 A&#xff0e;int a(5)&#xff1b;double *pda&#xff1b; B&#xff0e;double d(2.5)&#xff0c;*pd&d&#xff1b; C&#xff0e;dou…

uniapp时间戳转时间

时间戳转时间 utils页面 function timestampToTime(time) { const date new Date(time); const year date.getFullYear(); const month String(date.getMonth() 1).padStart(2, 0); // 月份从0开始&#xff0c;所以要加1&#xff0c;并补齐0 const day String(date…