2015-10-19 26 views
1

我想基于降序排列三场一包内的元组进行排序..排序元组基于多的Fileds

例:假设我有以下的包创建的分组:

{(s,3,my),(w,7,pr),(q,2,je)} 

我想排序在$ 0,$ 1,$ 2字段的上述分组袋中的元组,这样首先它将排序所有元组中的$ 0。它将选择最大$ 0值的元组。如果所有元组的$ 0都是相同的,那么它将按$ 1排序,依此类推。

排序应通过迭代过程为所有分组的行李。

假设,如果我们有databag类似:

{(21,25,34),(21,28,64),(21,25,52)} 

然后根据需要输出应该是这样的:

{(21,25,34),(21,25,52),(21,28,64)} 

请让我知道如果你需要任何更多的澄清

+0

那么你的输出应该如何呢? –

+0

上述数据包所需的输出为{(q,2,je),(s,3,my),(w,7,pr)} ..但是假设我们有数据包像{(21,25 ,(34),(21,28,64),(21,25,52)}然后根据需求输出应该是{(21,25,34),(21,25,52),(21,28 ,64)} ..请让我知道你是否需要更多的澄清。 –

+0

已将评论的预期输出添加到问题 –

回答

1

订购你的元组嵌套foreach。这将工作。

输入:

(1,s,3,my) 
(1,w,7,pr) 
(1,q,2,je) 


A = LOAD 'file' using PigStorage(',') AS (a:chararray,b:chararray,c:chararray,d:chararray); 
B = GROUP A BY a;                        
C = FOREACH B GENERATE A;                      
D = FOREACH C {                        
od = ORDER A BY b, c, d;                      
GENERATE od;                         
}; 

DUMP C测试结果(这类似于你的数据):

({(1,s,3,my),(1,w,7,pr),(1,q,2,je)}) 

输出:

({(1,q,2,je),(1,s,3,my),(1,w,7,pr)}) 

这将为所有的情况下工作。

生成具有最高值的元组:

A = LOAD 'file' using PigStorage(',') AS (a:chararray,b:chararray,c:chararray,d:chararray); 
B = GROUP A BY a;                        
C = FOREACH B GENERATE A;                      
D = FOREACH C { 
od = ORDER A BY b desc , c desc , d desc; 
od1 = LIMIT od 1;       
GENERATE od1;        
}; 
dump D; 

生成具有最高值的元组,如果所有的三个区域是不同的,如果所有的记录都相同,或者如果场1和场2都相同,则全部归还元组。

A = LOAD 'file' using PigStorage(',') AS (a:chararray,b:chararray,c:chararray,d:chararray); 
B = GROUP A BY a;                        
C = FOREACH B GENERATE A; 
F = RANK C; //rank used to separate out the value if two tuples are same          
R = FOREACH F {  
dis = distinct A;          
GENERATE rank_C,COUNT(dis) AS (cnt:long),A;     
}; 
R3 = FILTER R BY cnt!=1; // filter if all the tuples are same 
R4 = FOREACH R3 {       
fil1 = ORDER A by b desc, c desc, d desc; 
fil2 = LIMIT fil1 1;      
GENERATE rank_C,fil2;        
}; // find largest tuple except if all the tuples are same. 
R5 = FILTER R BY cnt==1; // only contains if all the tuples are same 
R6 = FOREACH R5 GENERATE A ; // generate required fields 
F1 = FOREACH F GENERATE rank_C,FLATTEN(A); 
F2 = GROUP F1 BY (rank_C, A::b, A::c); // group by field 1,field 2 
F3 = FOREACH F2 GENERATE COUNT(F1) AS (cnt1:long) ,F1; // if count = 2 then Tuples are same on field 1 and field 2 
F4 = FILTER F3 BY cnt1==2; //separate that alone 
F5 = FOREACH F4 {      
DIS = distinct F1;     
GENERATE flatten(DIS); 
}; 
F8 = JOIN F BY rank_C, F5 by rank_C; 
F9 = FOREACH F8 GENERATE F::A; 
Z = cross R4,F5; // cross done to genearte if all the tuples are different 
Z1 = FILTER Z BY R4::rank_C!=F5::DIS::rank_C; 
Z2 = FOREACH Z1 GENERATE FLATTEN(R4::fil2); 
res = UNION Z2,R6,F9; // Z2 - contains value if all the three fields in the tuple are diff holds highest value, 
//R6 - contains value if all the three fields in the tuple are same 
//F9 - conatains if two fields of the tuples are same 
dump res; 
+0

感谢您的帮助。我对它有一个更多的要求。对于上面的示例,我需要找出$ 0上的最高值的元组。如果$ 0对于所有元组是相同的,那么取数据库{(21,25,34),(21,25,52),(21,28,64)}为$ 1.So的最高值的元组,输出为{(21,28,64) }。如果所有的$ 0,$ 1和$ 2字段都是相同的,那么它应该返回所有的元组。 –

+0

编辑答案。有一点需要注意的是,如果所有三个字段都是相同的,那么你只会得到一个元组。如果该帖子解析了您的查询,请接受答案。 –

+0

感谢一吨Vignesh –