Hive 之 函数 03-系统内置函数 及 自定义函数

一、 系统内置函数

1.1 查看系统自带的函数

hive (default)> show functions;

1.2 显示自带的函数的用法

hive (default)> desc function func_name;

1.3 详细显示自带的函数的用法

hive (default)> desc function extended func_name;

二、 自定义函数

2.1 概述

当 Hive 提供的内置函数无法满足业务处理需要时,
此时就可以考虑使用用户自定义函数(UDF: user-defined function)。

根据用户自定义函数类别可以分为以下三种:

○ UDF(User-Defined-Function

一进一出

○ UDAF(User-Defined Aggregation Function

聚集函数,多进一出

类似于: count/max/min

○ UDTF(User-Defined Table-Generating Functions

一进多出

lateral view explore()

【注】几进几出的依据是 “有多少行”, 进了几行, 出了几行, 而不是参数的个数。

官方文档地址:https://cwiki.apache.org/confluence/display/Hive/HivePlugins

编程步骤:

	a. 继承 org.apache.hadoop.hive.ql.UDF
	
	b. 需要实现 evaluate 函数; evaluate 函数支持重载(处理逻辑就在这个函数中实现);
	
	c. 在 hive 的命令行窗口创建函数
	
		a)添加 jar
	
			add jar linux_jar_path
	
			【注】如果放在了 hive/lib 下, 仅第一次需要 add jar, 之后启动 hive 的时候, 会自动加载 lib 下的库;
	
		b)创建 function
	
			create [temporary] function [dbname.]function_name AS class_name;

			【注】指定了数据库名称, 在别的数据库中无法使用; 如果不指定, 默认为当前数据库; 如果创建的是 temporary的函数, 那么重启之后函数就失效了。 

	d. 在 hive 的命令行窗口删除函数

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

【注】如果创建的是临时的函数, 那么不需要删除, hive 关闭后就会自动失效;UDF 必须要有返回类型,可以返回 null,但是返回类型不能为 void

2.2 自定义 UDF 函数

2.2.1 创建一个Maven 工程;

2.2.2 导入依赖

<dependencies>
	<!--https://mvnrepository.com/artifact/org.apache.hive/hive-exec -->
	<dependency>
		<groupId>org.apache.hive</groupId>
		<artifactId>hive-exec</artifactId>
		<version>1.2.1</version>
	</dependency>
</dependencies>

2.2.3 创建一个 Java 类

package com.atguigu.hive;

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

/**
 * @ author: cybeyond
 * @ create: 2020-04-09-21:27
 */
public class MyUDF extends UDF {

    public int evaluate(int data) {
        return data + 5;
    }
}

2.2.4 生成 jar 包, 并拷贝到服务器中 Hive 的 lib 下

使用 IDEA 的 Maven 工具将 package build 出来, 然后去 target 中将对应生成的 jar 包(我这的名称是 mr-1.0-SNAPSHOT-jar-with-dependencies.jar)拷贝到 /opt/module/hive/lib下;

【注】放在了 hive/lib下之后, 重启 hive 就不需要再次添加 jar 包了;

2.2.5 添加 jar 包

hive (default)> add jar /opt/module/hive/lib/mr-1.0-SNAPSHOT-jar-with-dependencies.jar;
Added [/opt/module/hive/lib/mr-1.0-SNAPSHOT-jar-with-dependencies.jar] to class path
Added resources: [/opt/module/hive/lib/mr-1.0-SNAPSHOT-jar-with-dependencies.jar]

2.2.6 创建自定义函数

hive (default)> create function addFive as 'com.atguigu.hive.MyUDF';
OK
Time taken: 5.493 seconds

【注】as 后面的类名需要全限定类名;

2.2.7 使用 UDF 函数

hive (default)> select addFive(18);
OK
_c0
23
Time taken: 0.562 seconds, Fetched: 1 row(s)

2.3 自定义 UDTF 函数

自定义 UDTF 与 UDF 的区别是继承的类不同, UDTF 需要继承 GenericUDTF类, 并重写其中的三个方法: initialize()process()close()

之后的打包、 上传到hive/libadd jar和创建函数都与自定义 UDF 一样;

2.3.1 创建一个类

package com.atguigu.hive.udtf;

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;
import java.util.List;

/**
 * @ author: cybeyond
 * @ create: 2020-04-09-22:48
 */
public class MyUDTF extends GenericUDTF {

    private List<String> dataList = new ArrayList<>();

    @Override
    public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {

        // 1. 定义【输出数据】的列名
        List<String> fieldsNames = new ArrayList<>();
        fieldsNames.add("word");

        // 2. 定义【输出数据】的类型
        List<ObjectInspector> fieldOIs = new ArrayList<>();
        fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);

        return ObjectInspectorFactory.getStandardStructObjectInspector(fieldsNames, fieldOIs);
    }

    @Override
    public void process(Object[] objects) throws HiveException {

        // 1. 获取数据
        String data = objects[0].toString();

        // 2. 获取分隔符
        String splitKey = objects[1].toString();

        // 3. 切分数据
        String[] words = data.split(splitKey);

        // 4. 遍历写出
        for (String word : words) {
            // 5. 将数据放至集合
            dataList.clear();
            dataList.add(word);

            // 6. 写出数据的操作
            forward(dataList);
        }
    }

    @Override
    public void close() throws HiveException {

    }
}

2.3.2 打包上传服务器

2.3.3 添加 jar 包

hive (default)> add jay /opt/module/hive/lib/mr-1.0-SNAPSHOT-jar-with-dependencies.jar;
Usage: add [FILE|JAR|ARCHIVE] <value> [<value>]*
Query returned non-zero code: 1, cause: null

2.3.4 创建自定义函数

hive (default)> create temporary function splitWords as 'com.atguigu.hive.udtf.MyUDTF';
OK
Time taken: 0.09 seconds

2.3.5 使用 UDTF 函数

hive (default)> select splitWords('hello-world-my-love', '-');
OK
word
hello
world
my
love
Time taken: 0.681 seconds, Fetched: 4 row(s)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章