【问题标题】:Sort tuples in a bag based on multiple fileds根据多个字段对包中的元组进行排序
【发布时间】:2015-10-19 09:58:18
【问题描述】:

我正在尝试根据三个字段按降序对包内的元组进行排序..

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

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

我想根据 $0,$1,$2 字段对上述分组包中的元组进行排序,使其首先对所有元组中的 $0 进行排序。它将选择具有最大 $0 值的元组。如果所有元组的 $0 都相同,那么它将按 $1 排序,依此类推。

应通过迭代过程对所有分组的袋子进行排序。

假设我们有类似这样的数据包:

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

那么根据需求输出应该是这样的:

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

如果您需要更多说明,请告诉我

【问题讨论】:

  • 那么你的输出应该是什么样子?
  • 上述数据包所需的输出是{(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)}..如果您需要更多说明,请告诉我。
  • 添加了从评论到问题的预期输出

标签: apache-pig


【解决方案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 都相同,则获取$1 上价值最高的元组。因此对于数据包 {(21,25,34),(21,25,52),(21,28,64)},输出将是 {(21,28,64)} .如果所有的 $0,$1 和 $2 字段都相同,那么它应该返回所有的元组。
  • 编辑了答案。需要注意的一件事是,如果所有三个字段都相同,那么您将只得到一个元组。如果帖子解决了您的问题,请接受答案。
  • 嗨,Vignesh...如果所有三个字段都相同,仍在寻找获取所有元组的方法..请您帮我找到它。
  • 完成。有点棘手。用 cmets 更新了答案。如果所有元组都相同,这将允许您获得结果,然后它将返回所有元组,否则返回最大的元组。
  • 我需要你为上述数据集提供的最后一个帮助。如果我想根据以下标准对上述数据进行排序: 1.首先对所有元组按降序对 $0 字段进行排序,然后取具有最大 $0 字段的元组。 2.如果所有元组的 $0 字段都相同,则对归档的 $1 进行排序,并取归档 $1 最大的元组。 3.如果所有元组中的字段($0,$1)都相同,则取所有元组
猜你喜欢
  • 2021-03-08
  • 2019-10-28
  • 2013-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多