Hive 自定义函数

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

接下来,通过两个自定义函数来看看怎么进行自定义函数;

1、引入依赖编写代码

    <dependencies>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-exec</artifactId>
            <version>3.1.2</version>
        </dependency>
    </dependencies>

编写 UDF 逻辑

/**
 * 自定义实现 length() 函数
 */
public class MyStringLength extends GenericUDF {
    /**
     * @param arguments 输入参数类型的鉴别器对象
     * @return 返回值类型鉴别器对象
     * @throws UDFArgumentException
     */
    public ObjectInspector initialize(ObjectInspector[] arguments) throws UDFArgumentException {
        //判断输入参数个数
        if (arguments.length != 1) {
            throw new UDFArgumentLengthException("Input args length Error...");
        }
        //判断输入参数类型
        if (!arguments[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE)) {
            throw new UDFArgumentTypeException(0, "Input Args Type Error...");
        }
        //函数本身返回值 int,需要返回 int 类型的鉴别器对象
        return PrimitiveObjectInspectorFactory.javaIntObjectInspector;
    }

    /**
     * 函数处理逻辑
     *
     * @param arguments 输入参数
     * @return 返回值
     * @throws HiveException
     */
    public Object evaluate(DeferredObject[] arguments) throws HiveException {
        if (arguments[0].get() == null) {
            return 0;
        }
        return arguments[0].get().toString().length();
    }

    public String getDisplayString(String[] strings) {
        return "";
    }
}

编写UDTF

/**
 * 自定义 udtf 函数
 */
public class MyUDTF extends GenericUDTF {
    private ArrayList<String> outList = new ArrayList<String>();

    @Override
    public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
        //定义输出数据的列名和类型
        ArrayList<String> fieldNames = new ArrayList<String>();
        ArrayList<ObjectInspector> fieldOis = new ArrayList<ObjectInspector>();
        //添加输出数据的列名和类型
        fieldNames.add("LineToWorld");
        fieldOis.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);

        return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOis);
    }

    public void process(Object[] args) throws HiveException {
        //1、获取原始数据
        String arg = args[0].toString();
        //2、获取数据传入的第二个参数,此处为分隔符
        String splity = args[1].toString();
        //3、将原始数据按照传入的分隔符进行切分
        String[] fileds = arg.split(splity);
        //4、遍历切分后的结果,并写出
        for (String filed : fileds) {
            //集合复用,清空集合
            outList.clear();
            //将每一个单词添加到集合
            outList.add(filed);
            //写出集合内容
            forward(outList);
        }
    }

    public void close() throws HiveException {

    }
}

打包后上传到 hdfs

  上传到 jar 文件 hdfs

[hui@hadoop201 data]$ hadoop fs -put myhivefunc.jar /hivefun

2、创建函数并使用

创建字符串长度函数

create function mylen
    as 'org.wdh01.hive.fun.MyStringLength' using jar 'hdfs://hadoop201//hivefun/myhivefunc.jar';

使用

select mylen("123"),mylen("hello hive")
3    10

创建分词函数

create function mysplit  as 'org.wdh01.hive.fun.MyUDTF' using jar 'hdfs://hadoop201//hivefun/myhivefunc.jar';

使用

select mysplit("hello,world,hadoop,hive",",");
hello
world
hadoop
hive
posted @ 2022-12-27 12:34  晓枫的春天  阅读(135)  评论(0编辑  收藏  举报