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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章