【问题标题】:Group by tuple in Pig在 Pig 中按元组分组
【发布时间】:2017-05-04 05:09:13
【问题描述】:

我在这个问题上纠结了一段时间。我有一个如下所示的数据文件:

(1,N,N,5,High,H,House,d)
(1,N,N,6,High,H,House,a)    
(2,N,N,10,Low,H,House,t)    
(2,N,N,11,Medium,H,House,e)

我希望我的输出格式如下。我可以用 Pig 实现吗???

{1,(N,N),{(5,High),(H,House),d},{(6,High),(H,House),a}}

{2,(N,N),{(10,Low),(H,House),t}{(11,Medium),(H,House),e}}

我实际上尝试按第一列对其进行分组。

datafile = LOAD '/user/zbc/xyz.txt' USING PigStorage() AS (id:int, 
    flag1:chararray, flag2:chararray, typcode:chararray, typ_name:chararray, 
    groupcode:charray, groupname:chararray, date:chararray);

collected = FOREACH datafile Generate TOBAG(gst_id, TOTUPLE(flag1,flag2), 
TOBAG(TOTUPLE(typcode, typname), TOTUPLE(groupcode, groupname), date));

我不知道如何进一步进行。按“一个字段和一个元组”分组。

【问题讨论】:

    标签: tuples apache-pig


    【解决方案1】:

    嗯,您的方向是正确的,但您是自己创建袋子,而不是让 Pig 在分组时做。加载数据后,简化你的第二步,只创建你想要的元组,两个标志的组合:

    collected = FOREACH datafile Generate id, TOTUPLE(flag1, flag2), $3..;
    

    $3.. 告诉 Pig 从第四个(从 $0 开始)开始包含,因此您不必重复整个参数列表。现在你将拥有这个:

    (1,(N,N),5,High,H,House,d)
    (1,(N,N),6,High,H,House,a)
    (2,(N,N),10,Low,H,House,t)
    (2,(N,N),11,Medium,H,House,e)
    

    现在,您可以使用 group by 运算符按您想要的任何字段组合进行分组,在本例中是 id 和标志元组:

    desired_output = group collected by (id, $1);
    

    在此之后,您可以根据需要对数据进行分组:

    ((1,(N,N)),{(1,(N,N),6,High,H,House,a),(1,(N,N),5,High,H,House,d)})
    ((2,(N,N)),{(2,(N,N),11,Medium,H,House,e),(2,(N,N),10,Low,H,House,t)})
    

    编辑

    如果您不希望您分组的字段出现在最后一个包中,您可以使用嵌套的 foreach 将它们取出:

    filtered_output = foreach desired_output {
        AUX = foreach collected generate $2..;
        generate group, AUX;
    }
    

    输出:

    ((1,(N,N)),{(6,High,H,House,a),(5,High,H,House,d)})
    ((2,(N,N)),{(11,Medium,H,House,e),(10,Low,H,House,t)})
    

    【讨论】:

    • 感谢您的回复。但是在这种情况下,每个记录的分组依据字段都会重复,即(1,(N,N))。但我希望它只出现一次。就像这样 {1,(N,N),{(5,High),(H,House),d},{(6,High),(H,House),a}}......我能做到吗?
    • 那是how the group by works。对于每个组,您会得到一个包含两个字段的行:一个包含组值(idflags)的元组,一个包含该组中每个 original 行的包。原始行包含这些值,因此您可以再次获取它们。
    • @ShilpaGowda 检查我的编辑以避免这些重复值。
    • 非常感谢....这个输出看起来几乎与期望的输出相似....但是如果你观察到我期望的输出,即 {1,(N,N),{(5, High),(H,House),d},{(6,High),(H,House),a}}.... 我想创建一个包含 2 个包的单个包 .... 2袋子是 {(5,High),(H,House),d} 从第一个记录派生而来,{(6,High),(H,House),a} 从第二个记录派生而来......两者结合一起应该构成一个包,它用 id 和一个元组分组......我可以实现吗???最重要的是,我什至想命名我的包和元组
    • 可能有点晚了,但您可以将generate group, AUX; 换成generate group.id as id, group.b as b, AUX;。请注意,我填写了 b 字段,因为在上面没有命名第二个位置的东西。使用数据中存在的任何名称代替 b
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多