Hive中的函数

一、系统内置函数

1、查看系统自带的函数

hive (default)> show functions;

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

hive (default)> desc function max;

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

hive (default)> desc function extended max;

二、自定义函数

1、Hive 自带了一些函数,比如:max/min 等,但是数量有限,自己可以通过自定义 UDF 来方便的扩展。

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

3、根据用户自定义函数类别分为以下三种:
(1) UDF(User-Defined-Function)
一进一出

(2) UDAF(User-Defined Aggregation Function)
聚集函数,多进溢出
类似于:count/max/min

(3) UDTF(User-Defined Table-Generating Functions)
一进多出
如 lateral view explore()

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

(5) 编程步骤
A、继承 org.apache.hadoop.hive.ql.UDF
B、需要实现 evaluate 函数:evaluate 函数支持重载
C、在 hive 的命令行窗口创建函数
a、添加 jar

add jar linux_jar_path

b、创建 function

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

D、在 hive 的命令行窗口删除函数

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

(6) 注意事项
UDF 必须要有返回类型,可以返回 null,但是返回类型不能为 void。

三、自定义 UDF 函数

1、创建一个 maven 工程

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>

3、创建一个类

package udf;

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

/**
 * @description: 自定义一个 udf 函数实现将大写的字符串变为小写的字符串
 * @author: hyr
 * @time: 2020/2/19 21:48
 */
public class Lower extends UDF {
    public String evaluate(String s){
        if (s == null){
            return null;
        }
        return s.toLowerCase();
    }
}

4、用 maven 打成 jar 包,上传到服务器上

5、将 jar 包添加到 hive 的 classpath

hive (default)> add jar /opt/module/jardict/hivejar/abc-1.0-SNAPSHOT.jar;
Added [/opt/module/jardict/hivejar/abc-1.0-SNAPSHOT.jar] to class path
Added resources: [/opt/module/jardict/hivejar/abc-1.0-SNAPSHOT.jar]

6、创建临时函数与开发好的 java class 关联

hive (default)> create temporary function mylower as "udf.Lower";
OK
Time taken: 0.503 seconds

7、使用自定义的函数

hive (default)> select ename, mylower(ename) lowername from emp;
OK
ename	lowername
SMITH	smith
ALLEN	allen
WARD	ward
JONES	jones
MARTIN	martin
BLAKE	blake
CLARK	clark
SCOTT	scott
KING	king
TURNER	turner
ADAMS	adams
JAMES	james
FORD	ford
MILLER	miller
Time taken: 1.691 seconds, Fetched: 14 row(s)

四、自定义 UDTF 函数

1、需求
自定义一个 UDFTF 实现将一个任意分割符的字符串切割成独立的单词,例如:

Line:"hello,world,hadoop,hive" 
 
Myudtf(line, ",") 
 
hello 
world 
hadoop 
hive

2、代码实现

package 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;

/**
 * @description: 自定义 UDTF 函数
 * @author: hyr
 * @time: 2020/2/19 22:29
 */
public class MyUDTF extends GenericUDTF {
    private ArrayList<String> outList = new ArrayList<>();

    @Override
    public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
        // 1、定义输出数据的列名和类型
        ArrayList<String> fieldNames = new ArrayList<>();
        ArrayList<ObjectInspector> fieldOIs = new ArrayList<>();

        // 2、添加输出数据的列名和类型
        fieldNames.add("lineToWord");

        fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);

        return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);
    }

    public void process(Object[] args) throws HiveException {
        // 1、获取原始数据
        String arg = args[0].toString();

        // 2、获取数据传入的第二个参数,此处为分隔符
        String splitKey = args[1].toString();

        // 3、将原始数据按照传入的分隔符进行切分
        String[] fields = arg.split(splitKey);

        // 4、遍历切分后的结果,并写出
        for (String field : fields){
            // 集合为复用的,首先清空集合
            outList.clear();

            // 将每一个单词添加至集合
            outList.add(field);

            // 将集合内容写出
            forward(outList);
        }
    }

    public void close() throws HiveException {

    }
}

3、用 maven 打成 jar 包,并上传到服务器上

4、将 jar 包添加到 hive 的 classpath下

hive (default)> add jar /opt/module/jardict/hivejar/abc-1.0-SNAPSHOT.jar;
Added [/opt/module/jardict/hivejar/abc-1.0-SNAPSHOT.jar] to class path
Added resources: [/opt/module/jardict/hivejar/abc-1.0-SNAPSHOT.jar]

5、创建临时函数与开发好的 java class 关联

hive (default)> create temporary function myudtf as "udtf.MyUDTF";
OK
Time taken: 0.067 seconds

6、使用自定义函数
A、查看一下 words 表中的数据

hive (default)> select * from words;
OK
words.name
spark,hadoop,sqoop
scala,hive,hbase
Time taken: 0.064 seconds, Fetched: 2 row(s)

B、使用自定义函数

hive (default)> select myudtf(name, ",") word from words;
OK
word
spark
hadoop
sqoop
scala
hive
hbase
Time taken: 0.185 seconds, Fetched: 6 row(s)
发布了85 篇原创文章 · 获赞 72 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/a1786742005/article/details/104400038