Hive中的自定义函数允许用户扩展HiveQL,是一个非常强大的功能。Hive中具有多种类型的用户自定义函数。show functions命令可以列举出当前Hive会话中的所加载进来的函数,包括内置的以及用户加载的函数。

函数都有自身的使用文档,使用describe function命令就可以展示对应函数基本介绍。

标准函数UDF

用户自定义函数指的是一行数据中的一列或是多列数据作为参数然后返回结果是一个值的函数。这里用一个例子作为说明,我们当前有些数据表中存储的时间戳是以秒为单位的long值,如果想将这个long值转换为当天的hour值,就需要写一个UDF(尽管这个需求可以通过Hive中的标准函数解决...但我们举个例子)。

简单的UDF编写,直接继承org.apache.hadoop.hive.ql.exec.UDF,并实现evaluate方法,其中UDF抽象类中并没有严格要求evaluate的方法签名,这意味着可以使用Java中的重载,这样在实际使用时会根据传输参数的类型选择合适的方法;对于每行输入都会调用到evaluate函数,处理后的结果返回给Hive。

public class ToHourFunction extends UDF{
public String evaluate(String timeMillis) {
long longTimeMillis = Long.parseLong(timeMillis);
Date date = new Date(longTimeMillis * 1000L);
return String.format("%tk", date);
}
}

对于自定的UDF,为了让其他人在使用时能够得到一些帮助信息,最好添加@Description注解。注解中包含了这个函数的文档说明,用户也需要这个注解来说明自定义UDF如何使用,比如添加下面的注解:

@Description(name = "to_hour", value = "_FUNC_(x) - return long time millis(plus 1000) to current hour",
extended = "Example: to_hour(123232343) ")

value中的_FUNC_会被替换成用户为这个函数定义的“临时”函数名称,当添加这个jar包,并添加这个自定义函数,将其命名为to_hour

create temporary function to_hour as 'test.udf.ToHourFunction';

添加完成后,执行show functions命令就会额外添加一个我们的自定义函数,使用describe function to_hour能够显示出函数的具体使用方法(@Description中的内容)

to_hour(x) - return long time millis(plus 1000) to current hour

通过使用describe function extended to_hour可以显示@Descrption中的extended属性内容:

Example: to_hour(123232343)

除了UDF类,Hive还提供了一个对应的称为GenericUDF的类,GenericUDF是更为复杂的抽象概念,但是支持更好的null值处理。在Hive中本身就有很多函数是用GenericUDF实现的,我们可以参考他们的写法,比如GenericUDFAbs就是对一些基本的数据类型(SHORT/BYTE/INT/LONG/DOUBLE/FLOAT/STRING/DECIMAL)取绝对值的函数。

比如上面同样的to_hour函数,我们可以用GenericUDF重写一遍。继承GenericUDF函数之后,需要实现三个方法。

首先,initialize方法作为初始化使用,这个方法的目标是确定函数的参数类型,如果参数的数量以及类型不合法,要抛出异常以给用户必要的提示。to_hour方法中,我们需要界定输入参数必须为long类型,参数数量为1个,输出的结果为int类型。

    private IntWritable resultInt = new IntWritable();
private ObjectInspectorConverters.Converter inputConverter;
@Override
public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
if (arguments.length != 1) {
throw new UDFArgumentLengthException(
"to_hour requires 1 argument, got " + arguments.length);
}
if (arguments[0].getCategory() != ObjectInspector.Category.PRIMITIVE) {
throw new UDFArgumentException(
"to_hour only takes primitive types, got " + arguments[0].getTypeName());
}
PrimitiveObjectInspector argumentOIs = (PrimitiveObjectInspector) arguments[0];
PrimitiveObjectInspector.PrimitiveCategory inputType = argumentOIs.getPrimitiveCategory();
if (inputType != PrimitiveObjectInspector.PrimitiveCategory.LONG) {
throw new UDFArgumentTypeException(0, "Argument type should be long");
}
inputConverter = ObjectInspectorConverters
.getConverter(arguments[0], PrimitiveObjectInspectorFactory.writableLongObjectInspector);
return PrimitiveObjectInspectorFactory.writableIntObjectInspector;
}

方法evaluate的输入是一个DeferredObject[],通过initialize方法初始化的inputConverter将DeferredObject转换成对应的Writable对象,这一步中如果输入参数类型可变的话,这个inputConverter的意义就比较重大了,这一点请参考Hive中Abs函数的实现。后面就是将这个数据写到可重用的IntWritable对象中。

@Override
public Object evaluate(DeferredObject[] arguments) throws HiveException {
Object valueObj = arguments[0].get();
if (valueObj == null) {
return null;
}
valueObj = inputConverter.convert(valueObj);
long mills = ((LongWritable) valueObj).get() * 1000L;
String hourString = String.format("%tk", new Date(mills));
int hour = Integer.parseInt(hourString);
resultInt.set(hour);
return resultInt;
}

最后一个需要实现的方法是getDisplayString(),用在Hadoop Task内部,在使用此函数时显示调试信息。

@Override
public String getDisplayString(String[] children) {
StringBuilder sb = new StringBuilder();
sb.append("to_hour(");
if (children.length > 0) {
sb.append(children[0]);
for (int i = 1; i < children.length; i++) {
sb.append(",");
sb.append(children[i]);
}
}
sb.append(")");
return sb.toString();
}

截止目前,我们写的函数都只能创建为temp函数,如果想加入到Hive本身作为系统的不变函数使用,就需要修改org.apache.hadoop.hive.ql.exec.FunctionRegistry中的static静态块,将我们的函数加入进去,并重新编译部署hive(当然比较麻烦,不过仅需要替换hive-exec-版本号.jar文件即可)。稍微简单并灵活的方法是,我们写一个公用的shell加载脚本,每个hiveql文件在头上手动加载这个脚本,将公用的函数库加入进去。

Hive中的用户自定义函数UDF相关推荐

  1. hive 元数据 自定义_如何在Hive中创建自定义函数UDF及如何直接通过Impala的同步元数据重用UDF的jar文件-阿里云开发者社区...

    如何在Hive中创建自定义函数UDF及使用 如何在Impala中使用Hive的自定义函数 UDF函数开发 使用Intellij工具开发Hive的UDF函数,进行编译: 1.使用Intellij工具通过 ...

  2. 【Flink】Flink Table SQL 用户自定义函数: UDF、UDAF、UDTF

    本文总结Flink Table & SQL中的用户自定义函数: UDF.UDAF.UDTF. UDF: 自定义标量函数(User Defined Scalar Function).一行输入一行 ...

  3. hive 元数据 自定义_Hive中的用户自定义函数

    1.1 关于自定义函数 1)Hive 自带了一些函数,比如:max/min等,但是数量有限,自己可以通过自定义UDF来方便的扩展. 2)当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考 ...

  4. hive获取月份_【Hive】Hive中常用日期函数整理

    前言 使用hive进行时间处理的过程中,有时忘记一些常用的函数用法,现整理一下hive中常用日期函数,当做备忘录使用,忘记来翻阅一下. 1 时间戳转化日期函数 时间戳必须是10位,默认情况下转化为'y ...

  5. Hive中的多维分析函数

    Hive中的多维分析函数 众所周知,Hive是一个OLAP数据库,拥有着很强大的数据分析能力. 但是当我们一张表的维度信息特别多,并且需要各种维度组合的统计分析结果时就很不方便.比如一张表有5个维度, ...

  6. hive中的nvl函数

    hive中的nvl函数为判断是否为空值,和oracle判断空值使用的函数一致.nvl叫做空值转换函数. NVL函数的格式如下:NVL(expr1,expr2) 在mysql和sqlsever中分别使用 ...

  7. HIVE中的from_unixtime函数

    hive中的from_unixtime()函数,可以把时间戳格式的时间,转化为年月日时分秒格式的时间. from_unixtime的参数要求为整数,且单位为秒. 如果从业务系统拿到的时间戳格式的时间单 ...

  8. Hive 之 用户自定义函数 UDF UDAF UDTF

    一 什么是UDF UDF是UserDefined Function 用户自定义函数的缩写.Hive中除了原生提供的一些函数之外,如果还不能满足我们当前需求,我们可以自定义函数. 除了UDF 之外,我们 ...

  9. 4.2.11 Flink-流处理框架-Table API 与 SQL-函数(Functions)之用户自定义函数 UDF

    目录 1.写在前面 2.标量函数(Scalar Functions):一对一 3.表函数(Table Functions):一对多 4.聚合函数(Aggregate Functions) 5.表聚合函 ...

最新文章

  1. Ubuntu10.04安装Flash插件
  2. mysql创建非聚集索引_聚集索引和非聚集索引的区别
  3. vue data 值如何渲染_Vue执行流程解析
  4. 思科模拟器。计算机网络实验之四:RIPv2配置
  5. Ctr点击率预估理论基础及项目实战
  6. 聚合多个文件_python数据分析与挖掘(二十五)--- Pandas高级处理分组与聚合
  7. 顶配12599元!三星Galaxy S22国行价格来了...
  8. Babel 入门教程
  9. GitHub官网操作指南
  10. 【Https(二】】实战 openssl 配置 tomcat
  11. IDEA解决Tomcat乱码问题
  12. 01. Linux文件目录结构及存放内容(功能)
  13. Python xldr 读取xls 文件中时间格式处理
  14. 一群参与境内外赌博网站的开发的程序员被抓,网友:切勿面向监狱编程。。。...
  15. 《炼数成金-Linux内核探秘》笔记4
  16. 服务器光猫一直亮不响应,光猫光信号正常,且光猫和路由器都重启过,还是上不了网咋办?...
  17. threejs中设置物体的贴图+场景的6面贴图 +创建空间
  18. 大数据在车联网行业的实践与应用
  19. bison版本问题导致编译报错:‘parse.error‘ is not used
  20. Python修改论文的字体及其大小

热门文章

  1. 【C语言】字符串和字符串数组的输入和陷阱
  2. java rgb转yuv_总结各种RGB转YUV的转换公式
  3. devstack单机安装手记
  4. 服务器频繁FGC事件
  5. 解决W11休眠一段时间后自动关机的问题
  6. x(-x) Lowbit(x)
  7. 爬取猫眼top100并存入csv文件中
  8. 物联网系统由哪些技术组成
  9. Nvidia GPU 入门教程之 03 在 GPU 上运行 Python 脚本,对比cpu与gpu性能,检测a100性能(教程含源码)
  10. MFC编程 -- 添加菜单