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

Moh*_*hit 2 apache-pig

这是我想要处理我的数据的方式..来自猪...

A = Load 'data' ...

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

B = FOREACH A GENERATE my.udfs.extract('flag');
Run Code Online (Sandbox Code Playgroud)

所以基本上提取要么没有参数要么参与...'标志'

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

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

现在我如何在猪中实现这一点?

Lor*_*dig 12

首选方法是使用DEFINE.

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

例如:

鉴于以下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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后

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
Run Code Online (Sandbox Code Playgroud)


另一个选项(hack?):

在这种情况下,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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后

...
B = foreach A generate Extract2(true,*); --use flag
C = foreach A generate Extract2();
Run Code Online (Sandbox Code Playgroud)

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