我有一些缓慢变化的元数据,实时存储在HDFS上。我想编写一个猪作业,将这些行压缩到每个键的最新行。
例如,对于这些数据(为清晰起见而添加列标题):
ts meta key
-- ---- ---
1 foo id1
2 que id2
3 que id2
4 foo id1
5 pasa id2
6 pasa id2
7 foo id1
8 pasa id2
9 pasa id2
10 pasa id2
11 pasa id2
12 hombre id2
13 foo id1
14 foo id1
15 hombre id2
16 bar id1
17 bar id1
18 bar id1
19 bar id1
20 bar id1
我希望得到输出:
15 hombre id2
20 bar id1
我刚刚开始学习猪拉丁文的来龙去脉 - 有没有内置的方法在猪或某些图书馆中做到这一点,或者我应该看一下编写UDF?
答案 0 :(得分:6)
这是嵌套foreach的好地方:
A = LOAD '$input' AS (ts:int, meta:chararray, key:chararray);
B =
FOREACH (GROUP A BY key) {
byts = ORDER A BY ts DESC;
newest = LIMIT byts 1;
GENERATE FLATTEN(newest);
};
测试您的数据(我将其转换为制表符分隔符):
(20,bar,id1)
(15,hombre,id2)
使用这种方法,即使你有两行具有最新的时间戳,你也可以保证每一行只有一行(尽管这可能与你的数据无关)。
答案 1 :(得分:1)
你能做到的一种方法是:
A = LOAD 'myinput' USING PigStorage(' ')
AS (ts:int, meta:chararray, key:chararray) ;
-- Group by key, then find the newest ts for each key
B = FOREACH (GROUP A BY key)
GENERATE MAX(A.ts) AS newest,
FLATTEN(A) ;
-- Now that each line has the newest (appropriate) ts,
-- we can use it to filter the input
C = FILTER B BY newest == ts ;
输出:
(20,20,bar,id1)
(15,15,hombre,id2)
请注意,如果您不想拥有重复的ts
,则可以将其现在预测为:
C = FOREACH (FILTER B BY newest == ts)
GENERATE A::ts AS ts, A::meta AS meta, A::key AS key ;
但最好现在单独留下额外的ts
,并将其作为后来的FOREACH
的一部分进行预测,以限制作业的数量。
更新:此方法将返回每个键具有最大ts
的所有行。例如,如果数据是这样的:
(11,nope,id1)
(20,foo,id1)
(20,bar,id1)
然后它会返回foo
和bar
。