`
brandNewUser
  • 浏览: 456924 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hive中的用户自定义函数UDF

阅读更多

 

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方法初始化的inputConverterDeferredObject转换成对应的Writable对象,这一步中如果输入参数类型可变的话,这个inputConverter的意义就比较重大了,这一点请参考HiveAbs函数的实现。后面就是将这个数据写到可重用的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编写函数.docx

    本文主要讲解了 Hive 中自定义 UDF 函数的编写方法,包括创建 UDF 类、实现自定义函数逻辑、编译和打包 UDF jar 包、上传至 Hive 服务器并注册自定义函数。 一、创建 UDF 类 为了实现自定义 UDF 函数,需要创建一...

    HIVE自定义UDF函数

    而自定义用户定义函数(UDF)是 Hive 中的一个重要功能,允许用户根据自己的需求编写自定义函数,以便在 Hive 查询中使用。 如何在 Hive 中创建自定义 UDF 函数: 步骤一:编写 Java 程序 首先,您需要编写一个 ...

    hive的自定义函数

    Hive支持三种类型的自定义函数:用户定义的函数(UDF)、用户定义的聚合函数(UDAF)和用户定义的表生成函数(UDTF)。本篇文章主要介绍UDF的实现方法。 ##### 2.1 UDF的作用 - **扩展性**:允许开发人员根据具体...

    Spark不能使用hive自定义函数.doc

    ### Spark与Hive自定义函数兼容性问题解析 在大数据处理领域,Apache Spark 和 Apache Hive 都是非常重要的工具。Spark 是一种快速通用的大规模数据处理系统,而Hive 则是一种数据仓库工具,主要用于对存储在 ...

    hive UDF需要jar包

    在Hive中,UDF(User Defined Functions)是用户自定义函数,允许开发人员扩展Hive的内置功能,以满足特定的数据处理需求。Hive UDF的实现通常涉及到编写Java代码,并将其打包成JAR(Java Archive)文件,然后在Hive...

    hive 创建自定义函数 和 hive加载说明

    然而,有时Hive的内置函数并不能满足所有的业务需求,这时我们就需要创建自定义函数(UDF,User Defined Function)。这篇博文主要探讨了如何在Hive中创建自定义函数以及如何加载它们,这对于深化Hive的使用和解决...

    hive自定义udf函数实战

    udf函数,用户自定义函数,可以直接在sql语句中计算的函数 优点: 允许实现模块化的程序设计、方便修改代码、增加函数 UDF的执行速度很快,通过缓存计划在语句重复执行时降低代码的编译开销,比存储方法的执行效率...

    Hive的Udf函数进行数据脱敏

    Hive 的 User Defined Functions (UDFs) 是用户自定义函数,允许开发者扩展Hive的功能,以满足特定的数据处理需求。在这个场景中,我们关注的是如何使用UDF进行数据脱敏,特别是对敏感信息进行处理,例如手机号码、...

    自定义hive函数

    Hive 的灵活性之一在于支持用户自定义函数(UDF),包括用户定义的单行函数(UDF)、用户定义的多行函数(UDAF)和用户定义的表函数(UDTF)。这些自定义函数允许开发者扩展Hive的功能,以满足特定的业务需求。 ...

    hive数仓、hive SQL 、 hive自定义函数 、hive参数深入浅出

    3. Hive自定义函数(UDF): - UDF定义:用户可以编写Java代码实现特定功能的函数,然后在Hive SQL中调用。 - UDAF(用户定义的聚合函数):用于处理一组输入值并返回单个值,如自定义平均值、众数等。 - UDTF...

    hive按月份加减udf范例

    在Hive中,UDF(User Defined Function)是用户自定义函数,允许我们扩展Hive的功能以满足特定的业务需求。本示例主要讲解如何在Hive中实现按月份的加减操作,这在时间序列分析或周期性报告中非常常见。 标题"hive...

    hive自定义函数demo

    Hive自定义函数(User Defined Function,UDF)是用户编写并集成到Hive系统中的函数,用来处理Hive不内置支持的特定计算或转换任务。UDF接受单个输入参数并返回一个结果,非常适合进行简单的数据转换和计算。 2. *...

    hive-udf:hive自定义函数

    hive-udfhive自定义函数主要实现hive3种自定义函数1,udf函数,主要用于处理一对一数据处理2,udtf函数,主要用于处理一对多数据处理2,udaf函数,主要用与处理多对一数据聚合处理

    一些有用的自定义配置单元udf函数、特殊数组、json、数学、字符串函数。___下载.zip

    在IT行业中,尤其是在大数据处理领域,Hive是一...如果你在Hive项目中遇到特定的数据处理挑战,这些自定义函数可能就是你需要的解决方案。在实际应用中,记得根据具体需求选择并适配这些函数,以确保最佳的性能和结果。

    * hive脱敏UDF函数 *对一些敏感信息进行脱敏处理,替换位置可自定义,脱敏符号可随机也可自定义

    * 脱敏UDF函数 * 功能:对一些敏感信息进行脱敏处理,替换方式可选择自定义替换,如'#','*'等,,如不指定脱敏符号,使用个随机字符替换 * 脱敏位置可自定义,不指定位置,会对数据进行全脱敏 * 例如身份证信息: ...

    base64加密解密的hive udf函数

    本文将详细探讨如何在Hive中自定义User Defined Function(UDF)来实现Base64的加密和解密。 首先,我们需要了解Base64的基本原理。Base64是一种将任意二进制数据转化为ASCII字符集的方法,它通过将每3个字节转换为...

    hive-udf(两地址间距离计算+省市区位置解析(Java代码))

    为了满足特定的业务需求,Hive提供了用户定义函数(UDF)的功能,允许用户自定义处理数据的逻辑。在这个“hive-udf”项目中,我们主要探讨的是如何利用Java编写UDF来实现两个地址间的距离计算以及省市区位置的解析。...

    各种情况手机号清洗udf函数(hive impala)

    3. **Hive UDF**:在Hive中,我们可以创建自定义函数(UDF)来处理特定的数据清洗任务。首先,你需要编写一个Java类,该类继承自`org.apache.hadoop.hive.ql.udf.generic.GenericUDF`,并实现`evaluate`方法,该方法...

    HIve UDF 说明书

    内置聚合函数(UDAF)和表生成函数(UDTF)是Hive UDF中的高级功能。UDAF允许用户编写自定义的聚合逻辑,如自定义的count、sum、avg等;UDTF则允许用户将一行数据转换为多行数据,或者将多行数据合并为一行数据输出...

    获取最大分区UDTF函数.doc

    接下来,在Hive中创建永久自定义函数: ```sql drop function if exists maxParts; CREATE FUNCTION maxParts AS 'com.mingyang.GetMaxPartitionsUDTF' USING JAR 'hdfs://nameservice1/user/lib/max-partitions.jar...

Global site tag (gtag.js) - Google Analytics