2012-07-03 19 views
5

Tôi đang sử dụng PIG để tạo ra các nhóm từ các bộ như sau:PIG: Nhận tất cả các bộ ra khỏi một chiếc túi nhóm

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

-> 

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

này rất dễ dàng và làm việc. Nhưng vấn đề của tôi là để có được những điều sau: Từ các nhóm thu được, tôi muốn tạo ra một tập hợp của tất cả các bản ghi trong túi của nhóm:

a1, [b1, b2, b3] 

-> 

b1,b2 
b1,b3 
b2,b3 

Đây sẽ là dễ dàng nếu tôi có thể làm tổ "foreach" và trước hết lặp trên mỗi nhóm và sau đó trên túi của nó.

Tôi cho rằng tôi hiểu nhầm khái niệm và tôi sẽ đánh giá cao sự giải thích của bạn.

Cảm ơn.

Trả lời

15

Dường như bạn cần một sản phẩm Descartes giữa túi và chính nó. Để làm điều này, bạn cần phải sử dụng FLATTEN (túi) hai lần.

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; 

Hãy nhận biết rằng túi lớn sẽ tạo ra rất nhiều hàng. Để tránh nó, bạn có thể sử dụng TOP (...) trước khi san bằng:

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; 

Đối với đầu ra cụ thể của bạn, bạn có thể sử dụng một số bộ lọc trước khi san bằng:

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; 

Tôi hy vọng nó giúp.

Cheers

4

Cũng liên quan là thế này UnorderedPairs chức năng từ thư viện DataFu UDF. Nó tạo ra cặp của tất cả các mục trong một túi (trong trường hợp của bạn túi nhóm của bạn)

+0

Laurens là đúng. UDF này thực hiện chính xác những gì bạn cần và nó cũng là cách hiệu quả hơn so với một giải pháp dựa trên Pig thuần túy sử dụng sản phẩm Descartes. Nhân tiện, URL đã thay đổi: [UnorderedPairs] (http://datafu.incubator.apache.org/docs/datafu/1.2.0/datafu/pig/bags/UnorderedPairs.html) – matterhayes

1

Bạn có thể sử dụng câu lệnh GROUP ALL lợn để tạo

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)}) 
... 
Các vấn đề liên quan