2012-04-04 2 views
2

私は、Java UDFを使用してバッグ内のタプルをランク付けするJava UDFを作成しようとしています。 タプルには、ランク付けの基準となる値列と、最初に0に設定されたランク列があります。 タプルは、値列に基づいてソートされます。 すべてのタプルはバッグに入れられ、そのバッグはUDFに渡される新しいタプルの内側に配置されます。apache pig Java UDF - 属性値の変更がスティックしないようです

UDFはランク列を変更していますが、メソッドが終了すると値はすべて0に戻ります。値を "スティック"にする方法がわかりません。

ご協力いただければ幸いです。ここで

は私のJavaクラスは、ここで

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 
import org.apache.pig.FilterFunc; 
import org.apache.pig.EvalFunc; 
import org.apache.pig.backend.executionengine.ExecException; 
import org.apache.pig.data.DataType; 
import org.apache.pig.data.Tuple; 
import org.apache.pig.data.DataBag; 
import org.apache.pig.impl.logicalLayer.FrontendException; 
import java.util.Iterator; 
import org.apache.pig.PigWarning; 

/** 
* 
* @author Winter 
*/ 
public class Ranker extends EvalFunc<String>{ 
    @Override 
    public String exec(Tuple tuple) throws IOException { 
     if (tuple == null || tuple.size() == 0) { 
      return null; 
     } 


     List<Object> list = tuple.getAll(); 
     DataBag db = (DataBag) list.get(0); 
     Integer num = (Integer)list.get(1); 

     Iterator<Tuple>itr = db.iterator(); 
     boolean containsNonNull = false; 
     int i = 1; 
     double previous=0; 
     while (itr.hasNext()) { 

      Tuple t= itr.next(); 
      double d = (Double)t.get(num.intValue()); 
      int rankCol = t.size()-1; 
      Integer rankVal = (Integer)t.get(rankCol); 
      if(i == 0){  
       System.out.println("i==0"); 
       previous = d; 
       t.set(rankCol, i); 
      } else { 
       if(d == previous) 
        t.set(rankCol, i); 
       else{ 
        System.out.print("d!==previous|" + d + "|"+ previous+"|"+rankVal); 
        t.set(rankCol, ++i); 
        rankVal = (Integer)t.get(rankCol); 
        System.out.println("|now rank val" + rankVal); 
        previous = d; 
       } 
      } 
     } 


     return "Y"; 
    } 
} 

である私は豚のすべてを呼び出しています方法です -

REGISTER /myJar.jar; 
A = LOAD '/Users/Winter/milk-tea-coffee.tsv' as (year:chararray, milk:double); 
B = foreach A generate year, milk, 0 as rank; 
C = order B by milk asc; 
D = group C by rank order C by milk; 
E = foreach D generate D.C.year,D.C.milk,D.C.rank, piglet3.evalFunctions.Ranker(D.C,1); 
dump E; 

私は理由UDF内部にprint文のUDF内部にその作業を伝えることができます - d!==前へ| 21.2 | 0.0 | 0 |ランクval2 d!==前へ| 21.6 | 21.2 | 0 |ランクval3 d!==前へ| 21.9 | 21.6 | 0 |ランクval4 d !==前へ| 22.0 | 21.9 | 0 |今すぐランクval5 d!==前へ| 22.5 | 22.0 | 0 |ランクval6 d!==前へ| 22.9 | 22.5 | 0 |ランクval7 d!==前へ| 23.0 | 22.9 | 0 |ランクval8 d !==前へ| 23.4 | 23.0 | 0 |!23.8 | | 23.4 | 0 |今val9 D ==以前のランク付けになりましval11

をランク付け!| 23.9 | | 23.8 | 0今val10 D ==以前のランク付けしかし、私はEまたはDまたはCをダンプするとき、順位列には0しか含まれていません。

答えて

1

exec関数は、UDFから必要な出力を返す必要があります。あなたは現在、exec関数に渡されているタプルを修正してから、文字列 "Y"を返します。あなたのUDFからの出力は "Y"です。この場合、 "Y"ではなくTupleを返す必要があります。私は私の問題の一部は、タプルあなたをランク付けすることだと思い

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 
import org.apache.pig.FilterFunc; 
import org.apache.pig.EvalFunc; 
import org.apache.pig.backend.executionengine.ExecException; 
import org.apache.pig.data.DataType; 
import org.apache.pig.data.Tuple; 
import org.apache.pig.data.DataBag; 
import org.apache.pig.impl.logicalLayer.FrontendException; 
import java.util.Iterator; 
import org.apache.pig.PigWarning; 

/** 
* 
* @author Winter 
*/ 
public class Ranker extends EvalFunc<Tuple>{ 
    @Override 
    public Tuple exec(Tuple tuple) throws IOException { 
     if (tuple == null || tuple.size() == 0) { 
      return null; 
     } 


     List<Object> list = tuple.getAll(); 
     DataBag db = (DataBag) list.get(0); 
     Integer num = (Integer)list.get(1); 

     Iterator<Tuple>itr = db.iterator(); 
     boolean containsNonNull = false; 
     int i = 1; 
     double previous=0; 
     while (itr.hasNext()) { 

      Tuple t= itr.next(); 
      double d = (Double)t.get(num.intValue()); 
      int rankCol = t.size()-1; 
      Integer rankVal = (Integer)t.get(rankCol); 
      if(i == 0){  
       System.out.println("i==0"); 
       previous = d; 
       t.set(rankCol, i); 
      } else { 
       if(d == previous) 
        t.set(rankCol, i); 
       else{ 
        System.out.print("d!==previous|" + d + "|"+ previous+"|"+rankVal); 
        t.set(rankCol, ++i); 
        rankVal = (Integer)t.get(rankCol); 
        System.out.println("|now rank val" + rankVal); 
        previous = d; 
       } 
      } 
     } 


     return tuple; 
    } 
} 
+0

私は、次のコードは、あなたの意図に近いですが、私は何をしようとするのは非常に明確ではないと思いますそれを上のタプルと比較して、全体のバッグに取り組まなければなりません。 – Winter

+0

例えば、タプルは、その上の1番目のタプルが見えない限り、2番目のタプルであるかどうかを知りません。それで私はすべてのタプルを袋の中に入れ、その袋を新しいタプルの中に入れたのです。しかし、すべてを行うには完全に良い方法があるかもしれません。 – Winter

+0

あなたは正しかった!本当にありがとう! – Winter

関連する問題