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/” )且创建函数的用户与使用函数的用户有该文件的可读权限。示例
语句:
hdfs dfs -put ./hive_examples_jars /user/hive_examples_jars
hdfs dfs -chmod 777 /user/hive_examples_jars

步骤2 执行如下命令。
beeline -n Hive业务用户

步骤3 在Hive Server中定义该函数,以下语句用于创建永久函数:
CREATE FUNCTION addDoubles AS
‘com.huawei.bigdata.hive.example.udf.AddDoublesUDF‘ using jar ‘hdfs :/user/
hive_examples_jars/AddDoublesUDF.jar‘;
其中addDoubles是该函数的别名,用于SELECT查询中使用。
以下语句用于创建临时函数:
CREATE TEMPORARY FUNCTION addDoubles AS
‘com.huawei.bigdata.hive.example.udf.AddDoublesUDF‘ using jar ‘hdfs :/user/
hive_examples_jars/AddDoublesUDF.jar‘;
l addDoubles是该函数的别名,用于SELECT查询中使用。
l 关键字TEMPORARY说明该函数只在当前这个Hive Server的会话过程中定义使
用。

步骤4 在Hive Server中使用该函数,执行SQL语句:
SELECT addDoubles(1,2,3);
说明
若重新连接客户端再使用函数出现[Error 10011]的错误,可执行reload function;命令后再使用该
函数。

步骤5 在Hive Server中删除该函数,执行SQL语句:
DROP FUNCTION addDoubles;

----End
例子:

import org.apache.hadoop.hive.ql.exec.UDF;import java.util.ArrayList;

/** * Created by wulei on 2017/8/30. * 输入一个2016-03-01 10:09:08-360122000101这样的字符串数组, * 要拆分成2016-03-01 10:09:08和360122000101,分成两个字符串数组返回出来 */public class SubstrTimeUDF extends UDF{    public static ArrayList<String> evaluate(ArrayList<String> times,boolean flag) {        Object obj = new Object();        ArrayList<String> al1 =  new ArrayList<String>();        ArrayList<String> al2 =  new ArrayList<String>();        for (String time:times             ) {            String str1 = time.substring(0,19);            String str2 = time.substring(20);            al1.add(str1);            al2.add(str2);        }

if(flag){            return al1;        }else{            return al2;        }    }

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~UDTF(user defined Table functions) 用于处理单行数据,并生成多个数据行。如上,差别在于需要继承的是GeneriUDTF,然后需要覆盖重写父类的三个抽象方法,输出后有几列,在initialize中定义,主要处理逻辑在process中实现,值得注意的是,forward输出需要集合形式,比如数组或者ArrayList。
例子:
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.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.text.DateFormat;import java.text.SimpleDateFormat;import java.util.ArrayList;

public class SubstrTrackUdtf 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);

return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);    }

@Override    public void process(Object[] args) throws HiveException {        String input = args[0].toString();        String[] test = input.split(";");        ArrayList<String> result = new ArrayList<String>();        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        for (int i = 0; i < test.length; i++) {            // 单独处理第一条数据            if (i == 0) {                result.add(test[i]);            } else {                // 判断当前数据和前一条数据的时间差是否满足条件                int j = result.size();                try {                    if ((df.parse(test[i]).getTime() - df.parse(result.get(j - 1)).getTime()) < 30 * 60 * 1000) {                        result.add(test[i]);                        if (i + 1 == test.length) {

forward(new String[]{result.toString()});                        }                    } else {                        forward(new String[]{result.toString()});                        result.clear();                        result.add(test[i]);                        // 判断是否是最后一条数据                        if (i + 1 == test.length) {                            forward(new String[]{result.toString()});                        }                    }                } catch (Exception e) {                    // e.printStackTrace();                    continue;                }            }        }

}

}

PS:如果Create function时报错,一般是你不小心,方法需要的类没有对应好。

时间: 2024-11-09 16:24:17

Hive自定义函数UDF和UDTF的相关文章

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 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

[Hive]Hive自定义函数UDF

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

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示例

简单自定义函数只需继承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)

首先什么是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 编写自定义函数UDF

一 新建JAVA项目 并添加 hive-exec-2.1.0.jar 和hadoop-common-2.7.3.jar hive-exec-2.1.0.jar 在HIVE安装目录的lib目录下 hadoop-common-2.7.3.jar在hadoop的安装目录下的\share\hadoop\common 二 编一个一个类并继承UDF 并重写evaluate方法 下面以rownum为例 package com.udf; import org.apache.hadoop.hive.ql.exec