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

Pig Latin の詳細を学び始めたばかりです。Pig または一部のライブラリでこれを行う組み込みの方法はありますか、または UDF の作成を検討する必要がありますか?

4

2 に答える 2

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)

この方法を使用すると、最新のタイムスタンプを持つ行が 2 つある場合でも、キーごとに 1 つの行だけが保証されます (ただし、これはデータには関係ありません)。

于 2013-08-26T21:13:56.753 に答える
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

于 2013-08-26T19:14:06.777 に答える