按pig中的时间戳获取最后一行

muk1a3rh  于 2021-06-24  发布在  Pig
关注(0)|答案(2)|浏览(280)

我有一些缓慢变化的元数据实时存储到hdfs中。我想写一个pig作业,将这些行压缩到每个键的最近一行。
例如,对于这些数据(为清晰起见添加了列标题):

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拉丁语的来龙去脉-在pig或某个库中是否已经有了一种内在的方法来实现这一点,或者我应该考虑编写一个udf吗?

llycmphe

llycmphe1#

这是嵌套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)

使用此方法,即使有两行具有最新时间戳,也可以保证每个键只有一行(尽管这对数据可能无关紧要)。

g9icjywg

g9icjywg2#

一种方法是:

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 限制工作的数量。
update:此方法将返回所有具有最大 ts 每把钥匙。例如,如果数据如下:

(11,nope,id1)
(20,foo,id1)
(20,bar,id1)

然后它将返回两者 foo 以及 bar .

相关问题