将自定义参数传递给java中的pig udf函数

时间:2013-11-19 20:51:08

标签: apache-pig

这是我希望处理数据的方式..来自猪......

A = Load 'data' ...

B = FOREACH A GENERATE my.udfs.extract(*);
or

B = FOREACH A GENERATE my.udfs.extract('flag');

所以基本上提取要么没有参数要么参加...'flag'

在我的udf方面......

@Override
    public DataBag exec(Tuple input) throws IOException {
           //if flag == true
              //do this
           //else
              // do that
     }

现在我如何在猪身上实现这个目标?

1 个答案:

答案 0 :(得分:12)

首选方法是使用DEFINE

  

,,在以下情况下使用DEFINE指定UDF函数:     
...
  的构造函数   function接受字符串参数。如果你需要使用不同的   构造函数参数用于对函数的不同调用   需要创建多个定义 - 每个参数集一个“

E.g:

鉴于以下UDF:

public class Extract extends EvalFunc<String> {

    private boolean flag;

    public Extract(String flag) {
        //Note that a boolean param cannot be passed from script/grunt
        //therefore pass it as a string
        this.flag = Boolean.valueOf(flag);
    }

    public Extract() {
    }

    public String exec(Tuple input) throws IOException {

        if (input == null || input.size() == 0) {
            return null;
        }
        try {
            if (flag) {
                ...
            }
            else {
                ...
            }
        }
        catch (Exception e) {
            throw new IOException("Caught exception processing input row ", e);
        }
    }
}

然后

define ex_arg my.udfs.Extract('true');
define ex my.udfs.Extract();
...
B = foreach A generate ex_arg(); --calls extract with flag set to true
C = foreach A generate ex(); --calls extract without any flag set


另一种选择(黑客?):

在这种情况下,UDF使用其noarg构造函数进行实例化,并在其exec方法中传递要评估的标志。由于此方法将元组作为参数,因此您需要首先检查第一个字段是否为布尔标志。

public class Extract extends EvalFunc<String> {

    public String exec(Tuple input) throws IOException {

        if (input == null || input.size() == 0) {
            return null;
        }
        try {
            boolean flag = false;
            if (input.getType(0) == DataType.BOOLEAN) {
                flag = (Boolean) input.get(0);
            }
            //process rest of the fields in the tuple
            if (flag) {
               ...
            }
            else {
               ...
            }
        }
        catch (Exception e) {
            throw new IOException("Caught exception processing input row ", e);
        }
    }
}

然后

...
B = foreach A generate Extract2(true,*); --use flag
C = foreach A generate Extract2();

我宁愿坚持第一个解决方案,因为它闻起来。