开发者

Is it possible to cross-join a row in a relation with a tuple in that row in Pig?

I have a set of data that shows users, collections of fruit they like, and home city:

Alice\tApple:Orange\tSacramento
Bob\tApple\tSan Diego
Charlie\tApple:Pineapple\tSacramento

I would like to create 开发者_运维百科a pig query that correlates the number of users that enjoy tyeps of fruits in different cities, where the results from the query for the data above would look like this:

Apple\tSacramento\t2
Apple\tSan Diego\t1
Orange\tSacramento\t1
Pineapple\tSacramento\t1

The part I can't figure out is how to cross join the split fruit rows with the rest of the data from the same row, so:

Alice\tApple:Orange\tSacramento

becomes:

Alice\tApple\tSacramento 
Alice\tOrange\tSacramento

I know I can use TOKENIZE to split the string 'Apple:Orange' into the tuple ('Apple', 'Orange'), but I don't know how to get the cross product of that tuple with the rest of the row ('Alice').


One brute-force solution I came up with is to use the streaming to run the input collection through an external program, and handle the "cross join" to produce multiple rows per row there.

This seems like it should be unnecessary though. Are there better ideas?


You should use FLATTEN, which works great with TOKENIZE to do stuff like this.

b = FOREACH a GENERATE name, FLATTEN(TOKENIZE(fruits)) as fruit, city;

FLATTEN takes a bag and "flattens" it out across different rows. TOKENIZE breaks your fruits out into a bag (not a tuple like you said), and then FLATTEN does the cross-like behavior like you are looking for. I point out that it is a bag and not a tuple, because FLATTEN is overloaded and behaves differently with tuples.

I first learned of the FLATTEN/TOKENIZE technique in the canonical word count example, in which is tokenizes a word, then flattens the words out into rows.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜