2013-07-15 9 views
14

I-Daten, die bereits gruppiert ist und aggregiert, es sieht aus wie so:Pig: Get Top-n-Werte pro Gruppe

user value  count 
---- -------- ------ 
Alice third  5 
Alice first  11 
Alice second  10 
Alice fourth  2 
... 
Bob  second  20 
Bob  third  18 
Bob  first  21 
Bob  fourth  8 
... 

Für jeden Benutzer (Alice und Bob), möchte ich ihre oben abrufen n Werte (sagen wir 2), sortierte Terme von 'count'. So ist die gewünschte Ausgabe ich will, ist dies:

Alice first 11 
Alice second 10 
Bob first 21 
Bob second 20 

Wie kann ich das erreichen?

Antwort

28

Ein Ansatz ist

records = LOAD '/user/nubes/ncdc/micro-tab/top.txt' AS (user:chararray,value:chararray,counter:int); 
grpd = GROUP records BY user; 

top3 = foreach grpd { 
     sorted = order records by counter desc; 
     top = limit sorted 2; 
     generate group, flatten(top); 
}; 

Eingang ist:

Alice third 5 
Alice first 11 
Alice second 10 
Alice fourth 2 
Bob second 20 
Bob third 18 
Bob first 21 
Bob fourth 8 

Ausgang ist:

(Alice,Alice,first,11) 
(Alice,Alice,second,10 
(Bob,Bob,first,21) 
(Bob,Bob,second,20) 
+0

ausgezeichnet, danke! – Hoff

+0

Limit garantiert nicht, dass Sie die Top-Datensätze erhalten. –

+3

Die [docs] (https://pig.apache.org/docs/r0.7.0/piglatin_ref2.html#LIMIT) sagen, dass das Ausführen eines 'limit' nach der' 'Bestellung'' der Sammlung garantiert, dass Sie die Top-Aufnahmen –

4

Ich habe gerade eine Beobachtung gemacht, dass

top = limit sorted 2; 

oben ist eine eingebaute Funktion und kann einen Fehler melden, so dass die einzige Sache, die ich den Namen der Beziehung in diesem Fall und statt

generate group, flatten(top); 

, die den Ausgang

(Alice,Alice,first,11) 
(Alice,Alice,second,10 
(Bob,Bob,first,21) 
(Bob,Bob,second,20) 
gab geändert tat, war

Geänderte dass wie unten gezeigt -

records = load 'test1.txt' using PigStorage(',') as (user:chararray, value:chararray, count:int); 
grpd = GROUP records BY user; 
top2 = foreach grpd { 
     sorted = order records by count desc; 
     top1 = limit sorted 2; 
     generate flatten(top1); 
}; 

, die mir den gewünschten Ausgang gab, wie von Ihnen erforderlich -

(Alice,first,11) 
(Alice,second,10) 
(Bob,first,21) 
(Bob,second,20) 

Hoffe, das hilft.

+0

Danke für die Antwort .... – Ankit

Verwandte Themen