在java中向pig udf函数传递自定义参数

rekjcdws  于 2021-06-25  发布在  Pig
关注(0)|答案(1)|浏览(363)

这就是我处理数据的方式。。来自Pig。。

A = Load 'data' ...

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

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

所以基本上,extract要么没有参数,要么接受参数…''旗帜'
在我的自定义项方面。。。

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

现在如何在pig中实现这一点?

r6l8ljro

r6l8ljro1#

首选方法是使用define。
、使用define指定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();

我宁愿坚持第一种解决办法,因为这有味道。

相关问题