2012-07-03 23 views
5

używam wieprzowych do generowania grupy z krotek w następujący sposób:PIG: Zbierz wszystkie krotki z zgrupowane worka

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

-> 

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

Jest to łatwe i działa. Ale mój problem jest, aby co następuje: Z otrzymanych grup chciałbym wygenerować zbiór wszystkich krotek w worku grupy:

a1, [b1, b2, b3] 

-> 

b1,b2 
b1,b3 
b2,b3 

byłoby to łatwe, jeśli mogłem Gniazdo „foreach” i po pierwsze powtórzyć, nad każdą grupą, a następnie nad torbą.

Przypuszczam, że nie rozumiem tego pojęcia i doceniam twoje wyjaśnienie.

Dzięki.

Odpowiedz

15

Wygląda na to, że potrzebny jest kartezjański produkt między torbą a nią samą. Aby to zrobić, musisz użyć FLATTEN (torba) dwa razy.

Kod:

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; 

Należy pamiętać, że duże torby będzie produkować dużo wierszy. Aby tego uniknąć można użyć góry (...) przed spłaszczyć:

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; 

dla danego wyjścia można użyć trochę filtrowanie przed spłaszczyć:

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; 

Mam nadzieję, że to pomaga.

Cheers

4

Istotny jest również to UnorderedPairs funkcja UDF z biblioteki DataFu. Generuje par wszystkich elementów w worku (w przypadku, gdy pogrupowane torba)

+0

Laurens ma rację. Ten UDF robi dokładnie to, czego potrzebujesz i jest także o wiele bardziej wydajny niż czysty roztwór oparty na świni przy użyciu kartezjańskiego produktu. Nawiasem mówiąc, adres URL został zmieniony: [UnorderedPairs] (http://datafu.incubator.apache.org/docs/datafu/1.2.0/datafu/pig/bags/UnorderedPairs.html) – matterhayes

1

Można użyć instrukcji GROUP ALL świnia wygenerować

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)}) 
...