Hive(十三)自定义UDF与UDTF

自定义UDF

在Hive中,如果Hive原生提供的函数不能够处理数据,那么Hive允许用户自定义函数,在Hive3.X中,需要定义类继承GenericUDF类

自定义udf,添加pom依赖

<dependencies>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-exec</artifactId>
            <version>3.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-jdbc</artifactId>
            <version>3.1.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.glassfish</groupId>
                    <artifactId>javax.el</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-metastore</artifactId>
            <version>3.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-common</artifactId>
            <version>3.1.2</version>
        </dependency>
    </dependencies>

编写代码

package com.test;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
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;

//  传入两个字符串,获取第二个字符串在第一个字符串中第一次出现的下标位置
public class SelfUDF extends GenericUDF {
    // 初始化 - evaluate方法的返回值类型
    public ObjectInspector initialize(ObjectInspector[] ois) throws UDFArgumentException {
        // 确定参数个数
        if(ois.length != 2)
            throw new UDFArgumentException("参数个数必须为2!!!");
        // 返回结果,这个结果决定了函数的返回值类型
        return PrimitiveObjectInspectorFactory.javaIntObjectInspector;
    }

    // 函数要执行的逻辑需要覆盖在这个方法中
    public Object evaluate(DeferredObject[] dob) throws HiveException {
        // 获取第一个字符串
        String str = dob[0].get().toString();
        // 获取第二个字符串
        String sub = dob[1].get().toString();
        // 获取下标位置
        return str.indexOf(sub);
    }

    @Override
    public String getDisplayString(String[] s) {
        return null;
    }
}

上传到服务器上,在hive中添加jar包

hive>   add jar /HIVE-1.0-SNAPSHOT.jar;

 创建临时函数

create temporary function stringindexof as 'com.test.SelfUDF';

select stringindexof('abcdef','de');

自定义UDTF

UDTF解决输入一行,输出多行的需求

输入"hello,world,zhangsan,shanghai","," * 输出 * world * hello * world * zhangsan * shanghai

 编写代码

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;
 
/**
 * UDTF解决输入一行,输出多行的需求
 * 输入"hello,world,tom,shanghai",","
 * 输出
 * world
 * hello
 * world
 * tom
 * shanghai
 */
public class MyUDTF extends GenericUDTF {
    private List<String> wordList = new ArrayList<String>();
 
    @Override
    public StructObjectInspector initialize(StructObjectInspector argOIs)
            throws UDFArgumentException {
        /**
         * 输出数据类型说明:
         */
        List<String> fieldNames = new ArrayList<String>();
        fieldNames.add("word");
 
        List<ObjectInspector> fieldOIs = new ArrayList<>();
        fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
        return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);
    }
 
    @Override
    public void process(Object[] args) throws HiveException {
        String data = args[0].toString();
        String splitkey = args[1].toString();
        String[] words = data.split(splitkey);
        for (String word :
                words) {
            wordList.clear();
            wordList.add(word);
            forward(wordList);
        }
    }
 
    @Override
    public void close() throws HiveException {
    }
}

上传到服务器上,在hive中添加jar包

hive>   add jar /HIVE-1.0-SNAPSHOT.jar;

 创建临时函数

create temporary function myudtf as 'com.test.MyUDTF';

select myudtf('aa,bb,cc,dd',',');

使用SparkSQL和Hive API,可以通过以下步骤实现用户自定义函数(UDF)、聚合函数(UDAF)和表生成函数(UDTF): 1. 编写自定义函数的代码,例如: ``` // UDF def myUDF(str: String): Int = { str.length } // UDAF class MyUDAF extends UserDefinedAggregateFunction { override def inputSchema: StructType = StructType(StructField("value", StringType) :: Nil) override def bufferSchema: StructType = StructType(StructField("count", IntegerType) :: Nil) override def dataType: DataType = IntegerType override def deterministic: Boolean = true override def initialize(buffer: MutableAggregationBuffer): Unit = { buffer(0) = 0 } override def update(buffer: MutableAggregationBuffer, input: Row): Unit = { buffer(0) = buffer.getInt(0) + input.getString(0).length } override def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = { buffer1(0) = buffer1.getInt(0) + buffer2.getInt(0) } override def evaluate(buffer: Row): Any = { buffer.getInt(0) } } // UDTF class MyUDTF extends GenericUDTF { override def initialize(args: Array[ConstantObjectInspector]): StructObjectInspector = { // 初始化代码 } override def process(args: Array[DeferedObject]): Unit = { // 处理代码 } override def close(): Unit = { // 关闭代码 } } ``` 2. 将自定义函数注册到SparkSQL或Hive中,例如: ``` // SparkSQL中注册UDF spark.udf.register("myUDF", myUDF _) // Hive中注册UDF hiveContext.sql("CREATE TEMPORARY FUNCTION myUDF AS 'com.example.MyUDF'") // Hive中注册UDAF hiveContext.sql("CREATE TEMPORARY FUNCTION myUDAF AS 'com.example.MyUDAF'") // Hive中注册UDTF hiveContext.sql("CREATE TEMPORARY FUNCTION myUDTF AS 'com.example.MyUDTF'") ``` 3. 在SQL语句中使用自定义函数,例如: ``` -- 使用SparkSQL中的UDF SELECT myUDF(name) FROM users -- 使用Hive中的UDF SELECT myUDF(name) FROM users -- 使用Hive中的UDAF SELECT myUDAF(name) FROM users GROUP BY age -- 使用Hive中的UDTF SELECT explode(myUDTF(name)) FROM users ``` 以上就是使用SparkSQL和Hive API实现用户自定义函数(UDF、UDAF、UDTF)的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Allen019

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值