分享

HIVE UDF的一个问题

mvs2008 发表于 2015-12-9 18:34:21 [显示全部楼层] 只看大图 回帖奖励 阅读模式 关闭右栏 6 14100
本帖最后由 mvs2008 于 2015-12-9 18:34 编辑

自己写了个hive的UDF来实现Oracle中decode功能。
[mw_shl_code=java,true]package com.danny;

import org.apache.hadoop.hive.ql.exec.UDF;

import org.apache.hadoop.io.Text;

public class UDFDecode extends UDF {

        public String evaluate(Object... args) {

                String org_val, result = null;

                if (args.length == 0) {
                        result= null;
                } else {

                        if (args.length % 2 == 1) {
                                result= "No. of Parameters must be even";
                        } else {
                                for (int i = 0;i < args.length; i++) {
                                        org_val = args[0].toString();

                                        if (i % 2 == 0 && i != 0 && org_val == args[i - 1].toString()
                                                        ) {
                                                result= args.toString();
                                        }
                                        if(result==null)
                                        {
                                                result= args[args.length-1].toString();
                                        }
                                }
                        }

                }
                return result;
        }

}
[/mw_shl_code]
在eclipse中测试通过的。

无标题.png
但是上传到HIVE中运行的结果却不一样,这是为什么呢?
hive> select decode('a','a','b','c') from dual;   
Total MapReduce jobs = 1
Launching Job 1 out of 1
Number of reduce tasks is set to 0 since there's no reduce operator
Starting Job = job_1443597173524_0064, Tracking URL = http://master.hadoop:8088/proxy/application_1443597173524_0064/
Kill Command = /home/hadoop/hadoop-2.6.0/bin/hadoop job  -kill job_1443597173524_0064
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 0
2015-12-09 02:19:47,385 Stage-1 map = 0%,  reduce = 0%
2015-12-09 02:19:53,381 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 1.38 sec
2015-12-09 02:19:54,456 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 1.38 sec
2015-12-09 02:19:55,492 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 1.38 sec
MapReduce Total cumulative CPU time: 1 seconds 380 msec
Ended Job = job_1443597173524_0064
MapReduce Jobs Launched:
Job 0: Map: 1   Cumulative CPU: 1.38 sec   HDFS Read: 215 HDFS Write: 2 SUCCESS
Total MapReduce CPU Time Spent: 1 seconds 380 msec
OK
c
Time taken: 13.883 seconds, Fetched: 1 row(s)


已有(6)人评论

跳转到指定楼层
arsenduan 发表于 2015-12-9 19:53:37
输入数据不一样,输出结果也会不一样。
两个输入数据保持一致,在测试看看
回复

使用道具 举报

mvs2008 发表于 2015-12-10 08:33:25
我觉得不是输入参数个数或者参数值的问题。

[mw_shl_code=java,true]package com.danny;

import com.danny.UDFDecode;
//import com.danny.Args_check;


public class test_udf {

        public static void main(String[] args) {

                UDFDecode de=new UDFDecode();
                System.out.println(de.evaluate("a","a","b","c"));       
        }
       
}
[/mw_shl_code]

输出结果:
b
回复

使用道具 举报

mvs2008 发表于 2015-12-10 08:34:52
arsenduan 发表于 2015-12-9 19:53
输入数据不一样,输出结果也会不一样。
两个输入数据保持一致,在测试看看

我觉得不是输入参数个数或者参数值的问题。
[mw_shl_code=java,true]package com.danny;

import com.danny.UDFDecode;
//import com.danny.Args_check;


public class test_udf {

    public static void main(String[] args) {

        UDFDecode de=new UDFDecode();
        System.out.println(de.evaluate("a","a","b","c"));   
    }
     
}
[/mw_shl_code]

输出结果:
b


回复

使用道具 举报

cranberries8 发表于 2015-12-14 20:34:10
本帖最后由 cranberries8 于 2015-12-14 20:35 编辑

看了下你的程序逻辑:
就是在args[]   中 args 和 args[0]相同就输出相同的下一位数args[i+1] ,如果灭有出现和args[0]相同的就返回最后一位数字。
在hive中你输入的 args[4]={"a","a","b","c"},按逻辑来讲期望的输出是"b",但是运行的结果是"c"
也就是返回值是第一次i=0时赋值的。也就是在你的逻辑部分args[1],args[2],args[3] 都没有满足条件(i % 2 == 0 && i != 0 && org_val == args[i - 1].toString());
b的索引为2 (这是数字)一定满足前两个条件
也就是说没能满足第三个条件 org_val == args[i - 1].toString()

问题就是java 的== 是判断是不是同一个实例的(可能hive 对上述的参数重新生成了新对象也就是说 args[0] 和args[1]虽然值相同但是不是同一对象)
所以你可以试试将org_val == args[i - 1].toString() 改为 org_val.equal(args[i - 1].toString())
回复

使用道具 举报

mvs2008 发表于 2015-12-15 14:16:51
cranberries8 发表于 2015-12-14 20:34
看了下你的程序逻辑:
就是在args[]   中 args 和 args[0]相同就输出相同的下一位数args ,如果灭有出现和a ...

非常感谢,完美的解决了我的问题。对于==和equals的区别我了解的还不是很透彻(接触hadoop后才看了的ava)。如果可以大神可以指点一二,让我多一些参考。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条