我是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中解析它们

09-30 15:42
查看更多