1. 系统内置函数

1)查看系统自带函数

hive> show functions; 
hive> show functions like "*date*"; 

2)显示自带的函数的用法

hive> desc function upper; 

3)详细显示自带的函数的用法

hive> desc function extended upper; 

2. 自定义函数

1)说明

  • Hive 自带了一些函数,比如:max/min等,但是数量有限,自己可以通过自定义UDF来方便的扩展。
  • 当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数(UDF:user-defined
    function)。

2)自定义函数类别

  • UDF(User-Defined-Function): 一进一出
  • UDAF(User-Defined Aggregation Function):聚集函数, 多进一出,类似于:count/max/min
  • UDTF(User-Defined Table-Generating Functions): 一进多出,如 lateral view explore()

3)编程步骤

  • 继承org.apache.hadoop.hive.ql.exec.UDF
  • 需要实现evaluate函数;evaluate函数支持重载;
  • 在hive的命令行窗口创建函数

(1)添加 jar 包

add jar linux_jar_path;

(2)创建 function

create [temporary] function [dbname.]function_name AS class_name;

(3)也可以在hive命令行窗口删除自定义的函数

drop [temporary] function [if exists] [dbname.]function_name;

3. 自定义UDF函数

1)旧API

  • 在Idea上新建一个Maven工程com.atguigu.hiveplugin200105
  • 在pom.xml里添加依赖
<dependencies>
       <!-- https://mvnrepository.com/artifact/org.apache.hive/hive-exec -->
       <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-exec</artifactId>
            <version>3.1.2</version>
       </dependency>
</dependencies>
  • 新建一个包com.atguigu.hive,并在包中新建一个类MyUDF(注:一般写插件就是一个套路,继承点什么,实现点什么!)
package com.atguigu.hive;

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

/**
 * @author zjfstart
 * @create 2020-05-26-21:32
 *
 * 需求:旧API,输入一个字符串,返回字符串的长度
 */
public class MyUDF extends UDF {

    /**
     * 输入一个字符串,返回字符串的长度
     * @param input 输入的参数
     * @return 返回输入的参数的长度
     */
    public int evaluate (String input) {
        if (input == null) {
            return 0;
        }
        return input.length();
    }
}

  • 把代码打成jar包,并上传到服务器的/opt/module/hive/lib目录下(这里面一般存放hive的一些依赖的jar包)
  • 重启hive 或者 将jar包添加到hive的classpath
-- 重启hive
hiveservices.sh restart
-- 添加jar包
hive (default)> add jar /opt/module/hive/lib/hiveplugin200105-1.0-SNAPSHOT.jar;
  • 创建临时函数与开发好的java class关联
hive (default)> create temporary function mylength as "com.atguigu.hive.MyUDF";
  • 即可在hql中使用自定义的函数
hive (default)> select ename, mylength(ename) as name_len from emp limit 5;
-- 结果
+---------+-----------+
|  ename  | name_len  |
+---------+-----------+
| SMITH   | 5         |
| ALLEN   | 5         |
| WARD    | 4         |
| JONES   | 5         |
| MARTIN  | 6         |
+---------+-----------+

2)新API

package com.atguigu.hive;

/**
 * @author zjfstart
 * @create 2020-05-26-21:19
 */

import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
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;

/**
 * 需求:新API,输入一个字符串,返回字符串的长度
 */
public class MyNewUDF extends GenericUDF {

    /**
     * 对输入的方法做检查,以及约束输出的类型
     * @param arguments 输入的参数
     * @return 返回输入参数的长度
     * @throws UDFArgumentException
     */
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        // 对参数的个数进行检查
        if (arguments.length != 1) {
            throw new UDFArgumentLengthException("Wrong Arguments Count!");
        }
        // 对参数的类型进行检查
        if (!arguments[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE)) {
            throw new UDFArgumentTypeException(0, "Wrong Arguments Type!");
        }
        // 返回Int类型
        return PrimitiveObjectInspectorFactory.javaIntObjectInspector;
    }

    /**
     * 真正的实现逻辑的方法
     * @param arguments 输入的参数
     * @return 返回输入参数的长度
     * @throws HiveException
     */
    public Object evaluate(DeferredObject[] arguments) throws HiveException {
        Object o = arguments[0].get();
        if (o == null) {
            return 0;
        }
        return o.toString().length();
    }

    /**
     * 如果函数执行出错,错误提示
     * @param children
     * @return
     */
    public String getDisplayString(String[] children) {
        return "";
    }
}

  • 注:在hive中测试自定义函数的步骤与上述一致,这里不再赘述。
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐