2012-07-03 13 views
5

I PIG bin mit Gruppen von Tupeln zu erzeugen, wie folgt:PIG: Erhalten Sie alle Tupel aus einer gruppierten Tasche

a1, b1 
a1, b2 
a1, b3 
... 

-> 

a1, [b1, b2, b3] 
... 

Diese einfach ist und funktioniert. Aber mein Problem ist folgendes zu erhalten: Aus den erhaltenen Gruppen, würde Ich mag eine Menge aller Tupel in der Gruppe Tasche generieren:

a1, [b1, b2, b3] 

-> 

b1,b2 
b1,b3 
b2,b3 

Dies wäre einfach, wenn ich könnte Nest „foreach“ und zunächst Iterierte über jede Gruppe und dann über ihre Tasche.

Ich nehme an, dass ich das Konzept falsch verstehe, und ich werde Ihre Erklärung schätzen.

Danke.

Antwort

15

Es sieht so aus, als ob Sie ein kartesisches Produkt zwischen der Tasche und sich selbst benötigen. Um dies zu tun, müssen Sie FLATTEN (Tasche) zweimal verwenden.

Code:

inpt = load '.../group.txt' using PigStorage(',') as (id, val); 
grp = group inpt by (id); 
id_grp = foreach grp generate group as id, inpt.val as value_bag; 
result = foreach id_grp generate id, FLATTEN(value_bag) as v1, FLATTEN(value_bag) as v2; 
dump result; 

Beachten Sie, dass große Taschen werden viele Zeilen erzeugen. Um zu vermeiden, es könnten Sie TOP (...) vor abflachen verwenden:

inpt = load '....group.txt' using PigStorage(',') as (id, val); 
grp = group inpt by (id); 
id_grp = foreach grp generate group as id, inpt.val as values; 
result = foreach id_grp { 
    limited_bag = TOP(50, 0, values); -- all sorts of filtering could be done here 
    generate id, FLATTEN(limited_bag) as v1, FLATTEN(limited_bag) as v2; 
}; 
dump result; 

Für Ihre spezifische Leistung könnten Sie etwas Filterung vor abflachen verwenden:

inpt = load '..../group.txt' as (id, val); 
grp = group inpt by (id); 
id_grp = foreach grp generate group as id, inpt.val as values; 
result = foreach id_grp { 
    l = filter values by val == 'b1' or val == 'b2'; 
    generate id, FLATTEN(l) as v1, FLATTEN(values) as v2; 
}; 
result = filter result by v1 != v2; 

Ich hoffe, es hilft.

Prost

4

Ebenfalls relevant ist diese UnorderedPairs Funktion aus der DataFu UDF-Bibliothek. Es erzeugt Paare aller Elemente in einer Tasche (in Ihrem Fall Ihre gruppierten bag)

+0

Laurens ist direkt zu erzeugen. Dieses UDF macht genau das, was Sie brauchen, und es ist auch viel effizienter als eine reine Pig-basierte Lösung mit kartesischem Produkt. Die URL hat sich übrigens geändert: [UnorderedPairs] (http://datafu.incubator.apache.org/docs/datafu/1.2.0/datafu/pig/bags/UnorderedPairs.html) – matterhayes

1

Sie die Anweisung GROUP ALL Schwein verwenden können

A = -- Some bag 
B = -- Another bag 

groupedB = group B ALL; 
result = foreach A GENERATE 
    TOTUPLE(*), groupedB.$1; 

-- Will generate 
((a1), {(b1, b2, b3)}) 
((a2), {(b1, b2, b3)}) 
((a3), {(b1, b2, b3)}) 
... 
Verwandte Themen