Inceptor UDF

本文详细介绍了如何在Hive中实现一个自定义的UDAF(用户定义的聚合函数)。这个UDAF示例用于聚合多个字段的特定值,包括保存第一次出现的字段3值、最后一次出现的字段4值、字段5的最后一个非空非null有效值以及字段6所有非空非null有效值的连接字符串。文章通过代码解释了UDAF的四个关键方法:iterate、terminatePartial、merge和terminate的实现逻辑。
摘要由CSDN通过智能技术生成

package io.transwarp.inceptorudaf;

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

public class InceptorUDAF extends UDAF {
    /*
     * 在实现inceptor自定UDAF时,必须要继承UDAF类,还有在这个类的内部实现一个内部类实现接口UDAFEvaluator
     * 并重写里面的四个主要的方法
     *
     * 1. Iterate函数用于聚合。当每一个新的值被聚合时,此函数被调用。
     * 2. TerminatePartial函数在部分聚合完成后被调用。当hive希望得到部分记录的聚合结果时,此函数被调用。
     * 3. Merge函数用于合并先前得到的部分聚合结果(也可以理解为分块记录的聚合结果)。
     * 4. Terminate返回最终的聚合结果。
     *
     * 下面代码的逻辑要实现的是:
     * 1.保存fields3的第一次出现的任何值
     * 2.保存fields4的最后一个值
     * 3.保存fields5的最后一个非空非null的有效值
     * 4.将fields6的所有非空非null的有效值使用分隔符连接起来
     * 5.返回结果是“第一次出现的fields3,最后一次出现的fields4,fields5的最后一个非空非null的有效值,fields6所有的非空
     * 非null的有效值使用分隔符连接起来的字符串”
     */
    public static class GroupByUDAFEvaluator implements UDAFEvaluator{
        // 一个bean类记录字段和分隔符信息
        public static class PartialResult{
            String filed3;
            String filed4;
            String filed5;
            String filed6;
            String delimiter;
        }

        private PartialResult partial;

        public void init() {
            partial = null;
        }
        /*
         * 需要实现的第一个方法
         * 每个需要处理的处理都要经过的处理
         */
        public boolean iterate(String filed3,String filed4,String filed5 ,String filed6){
            if(filed3 == null && filed4 == null && filed5 == null && filed6 == null){
                return true;
            }

            if(partial == null ){
                partial = new PartialResult();
                partial.filed3 = "";
                partial.filed4 = "";
                partial.filed5 = "";
                partial.filed6 = "";
                partial.delimiter = "-";
                //filed3 logical
                partial.filed3 = filed3;
            }

            //filed4 logical
            partial.filed4 = filed4;
            //filed5 logical
            if(filed5 != null && !filed5.trim().equals("")) {
                partial.filed5 = filed5;
            }
            //filed6 logical
            if(filed6 != null && !filed6.trim().equals("")) {
                if(partial.filed6.length() > 0 ){
                    partial.filed6 = partial.filed6.concat(partial.delimiter);
                }
                partial.filed6 = partial.filed6.concat(filed6);
            }
            return true;
        }

        /*
         * 需要实现的第二个方法
         * 返回部分结果
         */
        public PartialResult terminatePartial(){
            return partial;
        }

        /*
         * 需要实现的第三个方法
         * 将两个部分结果合并
         */
        public boolean merge(PartialResult othe){
            if (othe == null){
                return true;
            }

            if(partial == null ){
                partial = new PartialResult();

                partial.filed3 = othe.filed3;
                partial.filed4 = othe.filed4;
                partial.filed5 = othe.filed5;
                partial.filed6 = othe.filed6;
                partial.delimiter = othe.delimiter;
            } else {
                //filed4 logical
                partial.filed4 = othe.filed4;
                //filed5 logical
                if(othe.filed5 != null && !othe.filed5.trim().equals("")) {
                    partial.filed5 = othe.filed5;
                }
                //filed6 logical
                if(othe.filed6 != null && !othe.filed6.trim().equals("")) {
                    if (partial.filed6.length() >0){
                        partial.filed6 = partial.filed6.concat(othe.delimiter);
                    }
                    partial.filed6 = partial.filed6.concat(othe.filed6);
                }
            }
            return true;
        }

        /*
         * 需要实现的第四个方法
         * 构造返回值类型,返回结果
         */
        public String terminate(){
            return "filed3:"+partial.filed3+" filed4:" +partial.filed4+"  filed5 :"+partial.filed5+" filed6: "+partial.filed6;
        }
    }
}
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值