Apache pig apache pig Java UDF-更改属性中的值不会';我好像没坚持住
我正在尝试编写一个JavaUDF,它将使用JavaUDF对包中的元组进行排序。 元组有一个值列(作为排名标准)和一个排名列(最初设置为0)。 元组根据值列进行排序。 所有元组都放在一个包中,该包放在传递给UDF的新元组中 但是,UDF正在修改秩列-一旦方法退出,所有值都将再次变为0。我不知道如何让值“粘住” 任何帮助都将不胜感激 这是我的java类Apache pig apache pig Java UDF-更改属性中的值不会';我好像没坚持住,apache-pig,Apache Pig,我正在尝试编写一个JavaUDF,它将使用JavaUDF对包中的元组进行排序。 元组有一个值列(作为排名标准)和一个排名列(最初设置为0)。 元组根据值列进行排序。 所有元组都放在一个包中,该包放在传递给UDF的新元组中 但是,UDF正在修改秩列-一旦方法退出,所有值都将再次变为0。我不知道如何让值“粘住” 任何帮助都将不胜感激 这是我的java类 import java.io.IOException; import java.util.ArrayList; import java.util.L
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";
}
}
我可以看出它在UDF中工作,因为UDF中有print语句-
d==以前的| 21.2 | 0.0 | 0 |现在排名2
d==以前的| 21.6 | 21.2 | 0 |现在排名3
d==以前的| 21.9 | 21.6 | 0 |现在排名4
d==以前的| 22.0 | 21.9 | 0 |现在排名5
d==以前的| 22.5 | 22.0 | 0 |现在排名6
d==以前的| 22.9 | 22.5 | 0 |现在排名7
d==以前的23.0 | 22.9 | 0 |现在排名8
d==以前的| 23.4 | 23.0 | 0 |现在排名第9
d==以前的| 23.8 | 23.4 | 0 |现在排名10
d==以前的23.9 | 23.8 | 0 |现在排名11
但是当我转储E、D或C时,秩列只包含0。exec函数必须从UDF返回您想要的输出。您当前正在修改传递给exec函数的元组,然后返回字符串“Y”--作为UDF输出的所有Pig都是“Y”。在这种情况下,应该返回元组而不是“Y” 我认为以下代码与您的意图很接近,但我不太清楚您试图做什么:
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;
}
}
import java.io.IOException;
导入java.util.ArrayList;
导入java.util.List;
导入org.apache.pig.FilterFunc;
导入org.apache.pig.EvalFunc;
导入org.apache.pig.backend.executionengine.ExecuteException;
导入org.apache.pig.data.DataType;
导入org.apache.pig.data.Tuple;
导入org.apache.pig.data.DataBag;
导入org.apache.pig.impl.logicalayer.FrontendException;
导入java.util.Iterator;
导入org.apache.pig.PigWarning;
/**
*
*@author-Winter
*/
公共类Ranker扩展EvalFunc{
@凌驾
公共元组执行(Tuple-Tuple)抛出IOException{
if(tuple==null | | tuple.size()==0){
返回null;
}
List=tuple.getAll();
databagdb=(DataBag)list.get(0);
整数num=(整数)list.get(1);
Iteratoritr=db.iterator();
布尔值containsNonNull=false;
int i=1;
双倍上一次=0;
while(itr.hasNext()){
元组t=itr.next();
double d=(double)t.get(num.intValue());
int rankCol=t.size()-1;
整数rankVal=(整数)t.get(rankCol);
如果(i==0){
System.out.println(“i==0”);
先前=d;
t、 组(rankCol,i);
}否则{
如果(d==上一个)
t、 组(rankCol,i);
否则{
系统输出打印(“d!==上一个|”+d+“|”+上一个+“|”+rankVal);
t、 组(rankCol,++i);
rankVal=(整数)t.get(rankCol);
System.out.println(“|now rank val”+rankVal);
先前=d;
}
}
}
返回元组;
}
}
我认为我的部分问题是,要对一个元组进行排序,你必须将它与上面的元组进行比较,这样你就必须处理整个袋子。例如,一个元组不知道它是否位于第二位,除非它能看到上面的第一位元组。这就是为什么我把所有的元组放在一个袋子里,然后把袋子放在一个新的元组里。但也许有一个更好的方法来完成这一切。
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;
}
}