Hive-编写UDTF函数一进多出(详细教程~~~)

创建项目的话,和之前写UDF函数的流程是一样的,如果不懂的,看这篇文章:
HIVE-编写UDF函数

在包udf中再创建一个MyUDTF类,继承UDTF函数,实现接口:

package com.atguigu.udf;

import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDTF;

public class MyUDTF extends GenericUDTF {
    public void process(Object[] args) throws HiveException {
        
    }

    public void close() throws HiveException {

    }
}

按提示所实现的方法有两个,其实不够,还要把初始化方法给他加上。

package com.atguigu.udf;

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.StructObjectInspector;

/**
 * 输入数据,hello,atguigu,hive
 * 输出数据:
 *  hello
 *  atguigu
 *  hive
 */
public class MyUDTF extends GenericUDTF {
    public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
        return super.initialize(argOIs);
    }

    //处理输入数据
    public void process(Object[] args) throws HiveException {

    }
    //收尾方法
    public void close() throws HiveException {

    }
}

完成的业务代码:

package com.atguigu.udf;

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 java.util.ArrayList;
import java.util.List;

/**
 * 输入数据,hello,atguigu,hive
 * 输出数据:
 *  hello
 *  atguigu
 *  hive
 */
public class MyUDTF extends GenericUDTF {

    //输出数据的集合
    private  ArrayList<String> outPutList= new ArrayList<String>();

    public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
        //输出数据的默认别名,可以被别名覆盖
        List<String> fieldNames=new ArrayList<String>();
        fieldNames.add("word");

        //输出数据的类型
        List<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();

        //最终返回值
        return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);
    }

    //处理输入数据:hello,atguigu,hive
    public void process(Object[] args) throws HiveException {
        //1.取出输入数据
        String input=args[0].toString();

        //2.按照","分割字符串
        String[] words = input.split(",");

        //3.遍历数据写出
        for (String word : words) {
            //清空集合
            outPutList.clear();

            //将数据放入集合
            outPutList.add(word);

            //输出数据
            forward(outPutList);
        }
    }
    //收尾方法
    public void close() throws HiveException {

    }
}

进行打包,重新拖入到hive的lib目录下:
添加到类路径:

hive (default)> add jar /opt/module/hive/lib/hive-demo-1.0-SNAPSHOT.jar
              > ;
Added [/opt/module/hive/lib/hive-demo-1.0-SNAPSHOT.jar] to class path
Added resources: [/opt/module/hive/lib/hive-demo-1.0-SNAPSHOT.jar]

创建函数:

hive (default)> create temporary function myudtf as "com.atguigu.udf.MyUDTF"; 
OK
Time taken: 0.733 seconds

注意:如果出现问题的话,怎么试都没法成功,就去重新启动hive
input表的数据:

hello,spark
hello,hive
hello,zhoujielun,linjunjie,dengziqi
hello,hadoop,mapreduce,yarn,common

创建表:

hive (default)>  create table input(words string) ;

加载数据进去:

load data local inpath '/opt/module/datas/input.txt'
into table input;

查看数据:

hive (default)> select * from input;
OK
input.words
hello,spark
hello,hive
hello,zhoujielun,linjunjie,dengziqi
hello,hadoop,mapreduce,yarn,common
Time taken: 1.386 seconds, Fetched: 4 row(s)

使用UDTF函数:

hive (default)> select my_udtf(words) from input;
OK
word
hello
spark
hello
hive
hello
zhoujielun
linjunjie
dengziqi
hello
hadoop
mapreduce
yarn
common
Time taken: 3.788 seconds, Fetched: 13 row(s)

实现了分割逗号,一进多出的效果。
上面这个UDTF函数只能够分割逗号,没法分割其他符合,如果想实现根据我传入的符号进行分割,可以对上面的代码坐下 修改:

package com.atguigu.udf;

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;

/**
 * 输入数据,hello,atguigu,hive
 * 输出数据:
 *  hello
 *  atguigu
 *  hive
 */
public class MyUDTF extends GenericUDTF {

    //输出数据的集合
    private  ArrayList<String> outPutList= new ArrayList<String>();

    public StructObjectInspector initialize(StructObjectInspector argOIs) throws UDFArgumentException {
        //输出数据的默认别名,可以被别名覆盖
        List<String> fieldNames=new ArrayList<String>();
        fieldNames.add("word");

        //输出数据的类型
        List<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>();
        fieldOIs.add(PrimitiveObjectInspectorFactory.javaStringObjectInspector);
        //最终返回值
        return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs);
    }

    //处理输入数据:hello,atguigu,hive
    public void process(Object[] args) throws HiveException {
        //1.取出输入数据
        String input=args[0].toString();
        String splitCharater = args[1].toString();
        //2.按照","分割字符串
        String[] words = input.split(splitCharater);

        //3.遍历数据写出
        for (String word : words) {
            //清空集合
            outPutList.clear();

            //将数据放入集合
            outPutList.add(word);

            //输出数据
            forward(outPutList);
        }
    }
    //收尾方法
    public void close() throws HiveException {

    }
}

再重新测试:

hive (default)> select my_udtf(words,',') from input;
OK
word
hello
spark
hello
hive
hello
zhoujielun
linjunjie
dengziqi
hello
hadoop
mapreduce
yarn
common
Time taken: 0.429 seconds, Fetched: 13 row(s)


hive (default)> select my_udtf(words,'hello') from input;
OK
word

,spark

,hive

,zhoujielun,linjunjie,dengziqi

,hadoop,mapreduce,yarn,common
Time taken: 0.539 seconds, Fetched: 8 row(s)

实现可以根据自己输入的分隔符来进行分割。

上面是通过UDTF实现分割的功能,接下来通过Hive来实现wordCount的功能,数据的话还是采用input表里面的数据:
第一步,对其进行炸裂:

 select explode(split(words,',')) word  from input;

这个语句和上面UDTF所实现的功能是一样的,结果如下:
在这里插入图片描述
实现完这个上面的结果之后,就要炸裂出来的结果进行分组,将单词相同的分成一组,所以对explode炸裂出来的结果取个别名, 对这个别名进行group by分组, 再count(*),就求出每个单词的个数:

select word,count(*) 
from  
(select explode(split(words,',')) word  from input)t1
group by word;

结果如下:

word	_c1
common	1
dengziqi	1
hadoop	1
hello	4
hive	1
linjunjie	1
mapreduce	1
spark	1
yarn	1
zhoujielun	1
Time taken: 36.758 seconds, Fetched: 10 row(s)
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以为你编写Java代码实现hive UDTF函数函数需要传入两个参数。以下是示例代码: ```java 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.StructObjectInspector; import org.apache.hadoop.io.Text; import java.util.ArrayList; public class MyUDTF extends GenericUDTF { @Override public StructObjectInspector initialize(ObjectInspector[] args) throws UDFArgumentException { // 检查参数个数是否正确 if (args.length != 2) { throw new UDFArgumentLengthException("MyUDTF函数需要传入两个参数"); } // 检查参数类型是否正确 if (!args[0].getCategory().equals(ObjectInspector.Category.PRIMITIVE) || !args[1].getCategory().equals(ObjectInspector.Category.PRIMITIVE)) { throw new UDFArgumentException("MyUDTF函数需要传入两个原始类型参数"); } // 定义输列名和类型 ArrayList<String> fieldNames = new ArrayList<String>(); ArrayList<ObjectInspector> fieldOIs = new ArrayList<ObjectInspector>(); fieldNames.add("output_col1"); fieldNames.add("output_col2"); fieldOIs.add(args[0]); fieldOIs.add(args[1]); return ObjectInspectorFactory.getStandardStructObjectInspector(fieldNames, fieldOIs); } @Override public void process(Object[] args) throws HiveException { Text input1 = (Text) args[0]; Text input2 = (Text) args[1]; // 处理逻辑 String output1 = input1.toString() + "_processed"; String output2 = input2.toString() + "_processed"; // 输结果 forward(new Object[]{output1, output2}); } @Override public void close() throws HiveException { // 关闭操作 } } ``` 这是一个简单的示例代码,你可以根据自己的需求行修改和补充。在使用过程中,需要将该代码编译成 jar 包,并在 Hive 中注册该 UDTF 函数,才能够使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

梦里Coding

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

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

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

打赏作者

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

抵扣说明:

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

余额充值