hive自定义函数UDF UDTF UDAF

Hive 自定义函数 UDF UDTF UDAF

1.UDF:用户定义(普通)函数,只对单行数值产生作用;

UDF只能实现一进一出的操作。

定义udf 计算两个数最小值

public class Min extends UDF {

        public Double evaluate(Double a, Double b) {

            if (a == null)
                a = 0.0;
            if (b == null)
                b = 0.0;
            if (a >= b) {
                return b;
            } else {
                return a;
            }
        }
    }

a)把程序打成jar包

b)添加jar包:add jar /run/jar/udf_test.jar;

c)创建临时函数:hive>CREATE TEMPORARY FUNCTION add_example AS ‘hive.udf.Add‘;

d)销毁临时函数:hive> DROP TEMPORARY FUNCTION add_example;

2.UDTF:User-Defined Table-Generating Functions,用户定义表生成函数

用来解决输入一行输出多行

继承org.apache.hadoop.hive.ql.udf.generic.GenericUDTF,
实现initialize, process, close三个方法。

UDTF首先会调用initialize方法,此方法返回UDTF的返回行的信息(返回个数,类型)。

初始化完成后,会调用process方法,真正的处理过程在process函数中,在process中,每一次forward()调用产生一行;如果产生多列可以将多个列的值放在一个数组中,然后将该数组传入到forward()函数。

最后close()方法调用,对需要清理的方法进行清理
例子:切分”key:value;key:value”字符串,返回结果为key, value两个字段。
import java.util.ArrayList;

 import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;
 import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
 import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
 import org.apache.hadoop.hive.ql.metadata.HiveException;
 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;

 public class ExplodeMap extends GenericUDTF{

     @Override
     public void close() throws HiveException {
         // TODO Auto-generated method stub
     }

     @Override
     public StructObjectInspector initialize(ObjectInspector[] args)
             throws UDFArgumentException {
         if (args.length != 1) {
             throw new UDFArgumentLengthException("ExplodeMap takes only one argument");
         }
         if (args[0].getCategory() != ObjectInspector.Category.PRIMITIVE) {
             throw new UDFArgumentException("ExplodeMap takes string as a parameter");
         }

         ArrayList<String> fieldNames = new ArrayList<String>();
         ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();
         fieldNames.add("col1");
         fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
         fieldNames.add("col2");
         fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);

         return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames,fieldOIs);
     }

     @Override
     public void process(Object[] args) throws HiveException {
         String input = args[0].toString();
         String[] test = input.split(";");
         for(int i=0; i<test.length; i++) {
             try {
                 String[] result = test[i].split(":");
                 forward(result);
             } catch (Exception e) {
                 continue;
             }
         }
     }
 }
a)把程序打成jar包

b)添加jar包:add jar /run/jar/udf_test.jar;

c)创建临时函数:CREATE TEMPORARY FUNCTION explode_map AS ‘cn.itcast.hive.udtf.ExplodeMap‘;

d)销毁临时函数:hive> DROP TEMPORARY FUNCTION add_example;

udtf的使用:

UDTF有两种使用方法,一种直接放到select后面,一种和lateral view一起使用。

create table src(properties String);

	vi src.txt
	key1:value1;key2:value2;

load data local inpath ‘/root/hivedata/src.txt‘ into table src;

1:直接select中使用

select explode_map(properties) as (col1,col2) from src;

不可以添加其他字段使用
select a, explode_map(properties) as (col1,col2) from src;

不可以嵌套调用
select explode_map(explode_map(properties)) from src;

不可以和group by/cluster by/distribute by/sort by一起使用
select explode_map(properties) as (col1,col2) from src group by col1, col2;

2:和lateral view一起使用

select src.id, mytable.col1, mytable.col2 from src lateral view explode_map(properties) mytable as col1, col2;

3.UDAF:User- Defined Aggregation Funcation;用户定义聚合函数,可对多行数据产生作用;

等同与SQL中常用的SUM(),AVG(),也是聚合函数;

UDAF实现多进一出

UDAF实现有简单与通用两种方式:

import org.apache.hadoop.hive.ql.exec.UDAF;
import org.apache.hadoop.hive.ql.exec.UDAFEvaluator;
import org.apache.hadoop.io.IntWritable;

//UDAF是输入多个数据行,产生一个数据行
//用户自定义的UDAF必须是继承了UDAF,且内部包含多个实现了exec的静态类
public class MaxiNumber extends UDAF {
    public static class MaxiNumberIntUDAFEvaluator implements UDAFEvaluator {
        // 最终结果
        private IntWritable result;

        // 负责初始化计算函数并设置它的内部状态,result是存放最终结果的
        @Override
        public void init() {
            result = null;
        }

        // 每次对一个新值进行聚集计算都会调用iterate方法
        public boolean iterate(IntWritable value) {
            if (value == null)
                return false;
            if (result == null)
                result = new IntWritable(value.get());
            else
                result.set(Math.max(result.get(), value.get()));
            return true;
        }

        // Hive需要部分聚集结果的时候会调用该方法
        // 会返回一个封装了聚集计算当前状态的对象
        public IntWritable terminatePartial() {
            return result;
        }

        // 合并两个部分聚集值会调用这个方法
        public boolean merge(IntWritable other) {
            return iterate(other);
        }

        // Hive需要最终聚集结果时候会调用该方法
        public IntWritable terminate() {
            return result;
        }
    }
}

原文地址:https://www.cnblogs.com/alexzhang92/p/11072893.html

时间: 2024-10-12 21:46:18

hive自定义函数UDF UDTF UDAF的相关文章

Hive自定义函数(UDF、UDAF)

当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数. UDF 用户自定义函数(user defined function)–针对单条记录. 创建函数流程 1.自定义一个Java类 2.继承UDF类 3.重写evaluate方法 4.打成jar包 6.在hive执行add jar方法 7.在hive执行创建模板函数 8.hql中使用 Demo01: 自定义一个Java类 package UDFDemo; import org.apache.hadoop.hive.

Hive自定义函数UDF和UDTF

UDF(user defined functions) 用于处理单行数据,并生成单个数据行. PS: l 一个普通UDF必须继承自"org.apache.hadoop.hive.ql.exec.UDF".l 一个普通UDF必须至少实现一个evaluate()方法,evaluate函数支持重载. 主要步骤如下: 步骤1 把以上程序打包成AddDoublesUDF.jar,并上传到HDFS指定目录下(如" /user/hive_examples_jars/" )且创建函

[Hive]Hive自定义函数UDF

当Hive提供的内置函数无法满足你的业务处理需要时,此时就可以考虑使用用户自定义函数 用户自定义函数(user defined function),针对单条记录. 编写一个UDF,需要继承UDF类,并实现evaluate()函数.在查询执行过程中,查询中对应的每个应用到这个函数的地方都会对这个类进行实例化.对于每行输入都会调用到evaluate()函数.而evaluate()函数处理的值会返回给Hive.同时用户是可以重载evaluate方法的.Hive会像Java的方法重载一样,自动选择匹配的

Hive自定义函数UDF示例

简单自定义函数只需继承UDF类,然后重构evaluate函数即可 LowerCase.java: package com.example.hiveudf; import org.apache.hadoop.hive.ql.exec.UDF; public final class LowerCase extends UDF { public String evaluate(final String s) { if (s == null) { return null; } return new St

Hive 自定义函数 UDF UDAF UDTF

UDF:用户定义(普通)函数,只对单行数值产生作用: 继承UDF类,添加方法 evaluate() /** * @function 自定义UDF统计最小值 * @author John * */ public class Min extends UDF { public Double evaluate(Double a, Double b) { if (a == null) a = 0.0; if (b == null) b = 0.0; if (a >= b) { return b; } el

hive自定义函数(UDF)

首先什么是UDF,UDF的全称为user-defined function,用户定义函数,为什么有它的存在呢?有的时候 你要写的查询无法轻松地使用Hive提供的内置函数来表示,通过写UDF,Hive就可以方便地插入用户写的处理代码并在查询中使用它们,相当于在HQL(Hive SQL)中自定义一些函数,首先UDF必须用java语言编写,Hive本身就是用java写的. 编写UDF需要下面两个步骤: 1.继承org.apache.hadoop.hive.ql.UDF 2.实现evaluate函数,这

Hive自定义函数的学习笔记(1)

前言: hive本身提供了丰富的函数集, 有普通函数(求平方sqrt), 聚合函数(求和sum), 以及表生成函数(explode, json_tuple)等等. 但不是所有的业务需求都能涉及和覆盖到, 因此hive提供了自定义函数的接口, 方便用户扩展. 自己好像很久没接触hadoop了, 也很久没博客了, 今天趁这个短期的项目, 对hive中涉及的自定义函数做个笔记. 准备: 编写hive自定义函数前, 需要了解下当前线上hive的版本. hive --vesion 比如作者使用到的hive

T-SQL: 17 个与日期时间相关的自定义函数(UDF),周日作为周的最后一天,均不受 @@DateFirst、语言版本影响!

原文:T-SQL: 17 个与日期时间相关的自定义函数(UDF),周日作为周的最后一天,均不受 @@DateFirst.语言版本影响! CSDN 的 Blog 太滥了!无时不刻地在坏! 开始抢救性搬家 ... ... 到这里重建家园 /* T-SQL: 17 个与日期时间相关的自定义函数(UDF),周日作为周的最后一天,均不受 @@DateFirst.语言版本影响 都是从老文章里收集或提炼出来的! 提示: (@@Datefirst + datepart(weekday,@Date)) % 7 判

Hive自定义函数UDAF开发

Hive支持自定义函数,UDAF是接受多行,输出一行. 通常是group by时用到这种函数. 其实最好的学习资料就是官方自带的examples了. 我这里用的是0.10版本hive,所以对于的examples在 https://github.com/apache/hive/tree/branch-0.10/contrib/src/java/org/apache/hadoop/hive/contrib/udaf/example 我这里的功能需求是: actionCount(act_code,ac