这是我希望处理数据的方式..来自猪......
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
}
现在我如何在猪身上实现这个目标?
答案 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();
我宁愿坚持第一个解决方案,因为它闻起来。