2013-08-26 42 views
3

我有存儲在實時到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?你可以做到這一點

回答

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) 

用這種方法你保證即使您有兩行最新的時間戳(儘管這對您的數據無關緊要),每個鍵只需一行。

+0

謝謝,這工作得很好。我有點擔心,排序不會規模以及來自@ mr2ert的解決方案,但有一個結果行結束了希望,所以我會等到試圖優化之前出現的性能問題。 –

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) 

然後,它會同時返回foobar

+0

這個解決方案也很不錯 - 我拿起從@WinnieNicklaus的一個,因爲它與每個鍵的單行結束了,但我從來沒有真正想過時間戳的碰撞無論如何,所以任何一個可能會工作得很好。 –