2015-12-06 96 views
1

我是Pig腳本編程的新手。將多個參數傳遞給Pig篩選器UDF

我希望將多個參數傳遞給豬過濾器UDF,但我得到錯誤「無效標投影:A柱需要從一個關係預計它被用作標」

我做以下腳步。

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); 

對於上述所有的選項,我收到同樣的錯誤「無效標投影:A柱需要從一個關係預計它可以作爲一個標量。」

對於第一種情況,我的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? 「無效標量投影」錯誤背後的原因是什麼?

在此先感謝您的幫助。

回答

0

我不完全確定你在用你的UDF來計算什麼,因爲你的問題描述有點含糊,但在你所有的三個代碼示例中,你試圖將一個關係傳遞給你的UDF,真的有意義(輸入,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的用途;只需傳遞儘可能多的參數,然後在UDF內部解析它們.get(i)

+0

非常感謝GoBrewers14爲您提供的答覆。我想要的是,我想根據關係中的某些值過濾數據。例如,我只想要部門10的薪水低於10000的員工。'emp = load'/emp.csv'使用PigStorage(',')作爲(名稱,部門); filteremp = FILTER emp由FilterUDF(emp,10,1000);'和在UDF中,我打算從emp關係中使用get(1)提取部分,然後應用我的邏輯。可能有其他方法來實現這一點,但我想要遵循這一點。 – gauravbhide

+0

1)。您使用這種方式比使用UDF更復雜。 2)。當沒有名爲'salary'的列時,如何過濾'salary'? – gobrewers14

+0

抱歉忘記在加載數據時添加薪水列。 'emp = load'/emp.csv'使用PigStorage(',')作爲(名稱,部門,薪水); filteremp = FILTER emp通過FilterUDF(emp,10,1000);' 然後得到(1)部門和得到(2)工資。 它會工作嗎?我究竟做錯了什麼?我想遵循相同的方式,那麼現有代碼中必須做什麼更改? – gauravbhide