我是Pig脚本的新手。
我想将多个参数传递给Pig过滤器UDF,但出现错误“无效的标量投影:需要从关系中投影列才能用作标量”
我正在执行以下步骤。
input = load '....';
dump input; /* working able to see data*/
output = FILTER input by not FilterUDF(input,val1,val2);
这没有用。所以我尝试跟随。
input = load '......';
dump input; /* working able to see data*/
dataWithVal = FOREACH input GENERATE $0,$1,val1,val2;
dump dataWithVal; /* working able to see data with values*/
output = FILTER dataWithVal by not FilterUDF(dataWithVal);
这也没有用。因此,我将值添加到文件中,将该文件复制到HDFS中,然后将其与输入数据交叉连接,但仍然遇到相同的错误。
input = load '........';
dump input; /* working able to see data*/
val = load '........';
dump val; /* working able to values*/
interData = cross input, val;
dump interData; /* working able to see cross joined data*/
output = FILTER interData by not FilterUDF(interData);
对于上述所有选项,我都会收到与“无效标量投影:需要从关系中投影列以将其用作标量”相同的错误。
对于第一种情况,我的FilterUDF结构如下。
import org.apache.pig.FilterFunc;
import java.io.IOException;
import org.apache.pig.data.Tuple;
public class FilterUDF extends FilterFunc {
public boolean exec(Tuple input, int val, String Val) throws IOException {
/*some code here*/
}
}
案例一尝试了但没有奏效。
import org.apache.pig.FilterFunc;
import java.io.IOException;
import org.apache.pig.data.Tuple;
public class FilterUDF extends FilterFunc {
private Tuple input;
private int Ival;
private String Sval;
public FilterUDF(Tuple input, int Ival, String Sval){
this.input = input;
this.Ival = Ival;
this.Sval = Sval;
}
public Boolean exec(Tuple arg0) throws IOException {
/*Some code*/
}
}
对于情况二和三,我的FilterUDF结构如下。
import org.apache.pig.FilterFunc;
import java.io.IOException;
import org.apache.pig.data.Tuple;
public class FilterUDF extends FilterFunc {
public Boolean exec(Tuple input) throws IOException {
/*some code here*/
}
}
我做错了什么?
如何将多个参数传递给Pig UDF?
“无效标量投影”错误背后的原因是什么?
在此先感谢您的帮助。
最佳答案
我不确定您要使用UDF计算什么,因为问题描述有点含糊,但是在所有三个代码示例中,您都试图将一个关系传递给UDF,这实际上没有任何意义。 (input,dataWithVal和interData是关系)。您需要传递它的值。假设您使用UDF断言val1和val2是相同的(或其他),那么您可以编写
input = LOAD '...'; /* load some data */
output = FILTER input BY FilterUDF(val1, val2);
您的UDF看起来像
import org.apache.pig.FilterFunc;
import java.io.IOException;
import org.apache.pig.data.Tuple;
public class FilterUDF extends FilterFunc {
public Boolean exec(Tuple input) throws IOException {
if (input == null || input.size() == 0)
return null;
int val1 = input.get(0) // gets val1 from pig
int val2 = input.get(1) // gets val2 from pig
/*rest of code*/
}
}
如您所见,您可以根据需要将尽可能多的参数传递给UDF。这就是
org.apache.pig.data.Tuple
的用途;只需根据需要传递尽可能多的参数,然后使用.get(i)
在UDF中解析它们