2015-12-06 3 views
1

Я новичок в сценариях Pig.Передайте mutiple параметры в Pig Filter UDF

Я хочу передать несколько параметров Свинья фильтра UDF, но я получаю ошибку «Invalid проекции скалярной: Колонка должна быть спроецирована из соотношения для его использования в качестве скалярных»

я делаю следующее шаги.

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

Для всех перечисленных выше вариантов, я получаю такую ​​же ошибку как «Invalid проекции скалярной: Колонка должна быть спроецирована из соотношения для его использования в качестве скаляра.»

Для первого случая моя структура 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, t действительно имеет смысл (входные данные, 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 (',') as (name, dept); filteremp = FILTER emp by FilterUDF (emp, 10,1000); 'и в UDF я планировал извлечь dept, используя get (1) из отношения emp, а затем применить свою логику. Могут быть другие способы достичь этого, но я хочу следовать этому. – gauravbhide

+0

1). Вы делаете этот *** путь *** более сложным, чем это должно быть, используя UDF. 2). Как вы можете отфильтровать «зарплату», когда нет столбца с именем «зарплата»? – gobrewers14

+0

Извините, забыл добавить столбец зарплаты при загрузке данных. 'emp = load '/emp.csv', используя PigStorage (',') как (имя, отдел, зарплата); filteremp = FILTER emp by FilterUDF (emp, 10,1000); ' , а затем получить (1) для отдела и получить (2) за зарплату. Будет ли это работать? Что я делаю не так? Я хочу следовать тому же пути, и какие изменения мне нужно сделать в существующем коде? – gauravbhide