假设我有intput_file.txt(user_id,event_code,event_date):
1,a,1
1,b,2
2,a,3
2,b,4
2,b,5
2,b,6
2,c,7
2,b,8
你可以看到,user_id = 2,有这样的事件:abbbcb
我想得到这样的结果:
1,{(a,1),(b,2)}
2,{(a,2),(b,6),(c,7),(b,8)}
因此,当我们使用相同代码的事件很少时,我只想采用最后一个事件。
请你分享一下提示吗?
此致 的Pawel
答案 0 :(得分:0)
您要描述的主要内容是GROUP BY
的作用。
在这种情况下:
B = GROUP A BY user_id;
通过user_id
一起获取您的记录。您的数据现在将如下所示:
1,{(a,1),(b,2)}
2,{(a,2),(b,6),(c,7),(b,8)}
你说你只想要最后一个(我假设你是指具有最大event_date
的那个)。为此,您可以使用FOREACH
进行嵌套ORDER BY
按日期排序,然后使用LIMIT
进行第一次排序。请注意,当存在关联时,这会有任意行为。
C = FOREACH B {
DA = ORDER A BY event_date DESC;
DB = LIMIT DA 1;
GENERATE FLATTEN(group), FLATTEN(DB.event_code), FLATTEN(DB.event_date);
}
您的数据现在应如下所示:
1,b,2
2,b,8
另一种选择是使用UDF在GROUP BY
给出的组上写一些自定义行为:
B = GROUP A BY user_id;
C = FOREACH B GENERATE YourUDFThatYouBuilt(group, A);
在那个UDF中你可以编写你想要的任何自定义行为(在这种情况下返回具有最大日期的元组)
答案 1 :(得分:0)
您似乎可以使用DistinctBy中的Apache DataFu UDF来实现此目的。给定一个包,这个UDF返回为给定字段找到的第一个实例。在您的情况下,您关心的字段是event_code。但是我们必须颠倒顺序,因为你实际上想要最后一个实例。
虽然有一个澄清。如果我错了,请纠正我,但我认为预期的输出是:
1,{(a,1),(b,2)}
2,{(a,3),(b,6),(c,7),(b,8)}
也就是说,成员2发生(a,3)事件。成员1发生(a,2)事件。
以下是您可以这样做的方法:
-- pass in 1 because we want distinct by event code (position 1)
define DistinctBy datafu.pig.bags.DistinctBy('1');
FOREACH (GROUP A BY user_id) {
-- reverse so we can take the last event code occurrence
A_reversed = ORDER A BY event_date DESC;
-- use DistinctBy to get the first tuple having an occurrence of a field value
A_distinct_by_code = DistinctBy(A_reversed);
-- put back in order again
A_ordered = ORDER A_distinct_by_code BY event_date ASC;
GENERATE group as user_id, A_ordered.(event_code,event_date);
}