zoukankan      html  css  js  c++  java
  • Hive基础(19):Hive 函数(2) 自定义函数/自定义 UDF 函数/自定义 UDTF 函数

    3 自定义函数

    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 explode()
    4)官方文档地址
    https://cwiki.apache.org/confluence/display/Hive/HivePlugins
    5)编程步骤:
    (1)继承 Hive 提供的类
    org.apache.hadoop.hive.ql.udf.generic.GenericUDF
    org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
    (2)实现类中的抽象方法
    (3)在 hive 的命令行窗口创建函数
    添加 jar
    add jar linux_jar_path
    创建 function
    create [temporary] function [dbname.]function_name AS class_name;
    (4)在 hive 的命令行窗口删除函数
    drop [temporary] function [if exists] [dbname.]function_name;

    4 自定义 UDF 函数

    0)需求:
    自定义一个 UDF 实现计算给定字符串的长度,例如:
    hive(default)> select my_len("abcd"); 
    4
    1)创建一个 Maven 工程 Hive
    2)导入依赖
    <dependencies>
    <dependency>
    <groupId>org.apache.hive</groupId>
    <artifactId>hive-exec</artifactId>
    <version>3.1.2</version>
    </dependency>
    </dependencies>
    3)创建一个类
    package com.atguigu.hive;
    import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
    import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
    import org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException;
    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.PrimitiveObjectIn
    spectorFactory;
    /**
    * 自定义 UDF 函数,需要继承 GenericUDF 类
    * 需求: 计算指定字符串的长度
    */
    public class MyStringLength extends GenericUDF {
     /**
     *
     * @param arguments 输入参数类型的鉴别器对象
     * @return 返回值类型的鉴别器对象
     * @throws UDFArgumentException
     */
     @Override
     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
     */
     @Override
     public Object evaluate(DeferredObject[] arguments) throws 
    HiveException {
     if(arguments[0].get() == null){
     return 0;
     }
     return arguments[0].get().toString().length();
     }
     @Override
     public String getDisplayString(String[] children) {
     return "";
     } }
    4)打成 jar 包上传到服务器/opt/module/data/myudf.jar
    5)将 jar 包添加到 hive 的 classpath
    hive (default)> add jar /opt/module/data/myudf.jar;
    6)创建临时函数与开发好的 java class 关联
    hive (default)> create temporary function my_len as "com.atguigu.hive.
    MyStringLength";
    7)即可在 hql 中使用自定义的函数
    hive (default)> select ename,my_len(ename) ename_len from emp;
     

    5 自定义 UDTF 函数

    0)需求
    自定义一个 UDTF 实现将一个任意分割符的字符串切割成独立的单词,例如:
    hive(default)> select myudtf("hello,world,hadoop,hive", ",");
    hello
    world
    hadoop
    hive
    1)代码实现
    package com.atguigu.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.PrimitiveObjectIn
    spectorFactory;
    import java.util.ArrayList;
    import java.util.List;
    public class MyUDTF extends GenericUDTF {
     private ArrayList<String> outList = new ArrayList<>();
     @Override
     public StructObjectInspector initialize(StructObjectInspector argOIs) 
    throws UDFArgumentException {
     //1.定义输出数据的列名和类型
     List<String> fieldNames = new ArrayList<>();
     List<ObjectInspector> fieldOIs = new ArrayList<>();
     //2.添加输出数据的列名和类型
     fieldNames.add("lineToWord");
     
    fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
     return 
    ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, 
    fieldOIs);
     }
     @Override
     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);
     }
     }
     @Override
     public void close() throws HiveException {
     } 
    }
    2)打成 jar 包上传到服务器/opt/module/hive/data/myudtf.jar
    3)将 jar 包添加到 hive 的 classpath 下
    hive (default)> add jar /opt/module/hive/data/myudtf.jar;
    4)创建临时函数与开发好的 java class 关联
    hive (default)> create temporary function myudtf as
    "com.atguigu.hive.MyUDTF";
    5)使用自定义的函数
    hive (default)> select myudtf("hello,world,hadoop,hive",",");
     
     
     
     
     

    本文来自博客园,作者:秋华,转载请注明原文链接:https://www.cnblogs.com/qiu-hua/p/15141219.html

  • 相关阅读:
    箭头函数1
    变量结构赋值
    警惕32位程序在MethodImplOptions.Synchronized在x64机器上的同步缺陷[z]
    ListView的BeginUpdate()和EndUpdate()作用[z]
    如何用命令将本地项目上传到git[z]
    C# 两个datatable中的数据快速比较返回交集或差集[z]
    C# DataTable抽取Distinct数据(不重复数据)[z]
    【Thread】CountdownEvent任务并行[z]
    C#多线程--信号量(Semaphore)[z]
    VS2015一新建项目就出现未将对象引用设置到对象的实例怎么办?[z]
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/15141219.html
Copyright © 2011-2022 走看看