2012-05-15 13 views
5

bộ dữ liệu của tôi trông giống như sau:Flatten tuple giống như một túi

(A, (1,2)) 
(B, (2,9)) 

Tôi muốn "làm phẳng" các bản ghi trong Pig, về cơ bản lặp đi lặp lại mỗi bản ghi cho mỗi giá trị được tìm thấy trong khu vực nội-tuple, như vậy mà sản lượng dự kiến ​​là:

(A, 1) 
(A, 2) 
(B, 2) 
(B, 9) 

Tôi biết điều này là có thể khi các bộ (1,2) và (2,9) là các túi thay thế.

Trả lời

9

Thông tin chi tiết của bạn tốt; có thể bằng cách chuyển đổi bộ tuple trong túi. Giản đồ chúng tôi muốn nhắm đến là: {a: chararray, {(chararray)}} chẳng hạn: (A, {(1), (2)})

Đây là giải pháp cho vấn đề của bạn:

A = LOAD 'data.txt' AS (a:chararray,b:(b1:chararray,b2:chararray)); 
B = FOREACH A GENERATE a, TOBAG(b.b1,b.b2); 
C = FOREACH B GENERATE a, FLATTEN($1); 

Phần ma thuật là toán tử TOBAG.

+3

Tốt! Trong trường hợp này, tuple có hai phần tử (b.b1, b.b2). Làm thế nào để làm điều này khi kích thước của bộ tuple có thể thay đổi? – Marquez

+0

Tôi cũng muốn biết cách thực hiện điều này với Tuple có độ dài thay đổi. –

+0

Bạn có thể tự viết UDF cho mục đích đó. 'Túi DataBag = BagFactory.getInstance(). NewDefaultBag(); cho (int i = 0; i hobgoblin

0

Tôi biết đây là một chủ đề cũ nhưng tôi không thể làm cho phương pháp trên hoạt động. Tôi nghĩ rằng tôi sẽ chia sẻ những phát hiện của tôi.

input: (1-2-3, abc) 
     (4-5-6, xyz) 
desired output: 
     (1, abc) 
     (2, abc) 
     (3, abc) 
     (4, xyz) 
     (5, xyz) 
     (6, xyz) 

Ban đầu, tôi đã sử dụng STRSPLIT tạo bộ tuple dẫn đến đầu vào tương tự như trên nhưng không thành công.

output = FOREACH input GENERATE FLATTEN(TOBAG(STRSPLIT($0, '-'))), $1 

Điều này dẫn đến kết quả như sau:

(1,2,3,abc) 
(4,5,6,xyz) 

Tuy nhiên, khi tôi sử dụng tokenize và thay thế chức năng tôi có đầu ra mong muốn.

output = FOREACH input GENERATE FLATTEN(TOKENIZE(REPLACE($0,'-', ' '))), $1;