【问题标题】:Pig 10.0 - group the tuples and merge bags in a foreachPig 10.0 - 将元组分组并在 foreach 中合并包
【发布时间】:2013-03-27 14:07:13
【问题描述】:

我正在使用Pig 10.0。我想在 foreach 中合并包。假设我有以下visitors 别名:

(a, b, {1, 2, 3, 4}),
(a, d, {1, 3, 6}),
(a, e, {7}),
(z, b, {1, 2, 3})

我想对第一个字段上的元组进行分组,并将包与一组语义合并以获得以下元组:

({1, 2, 3, 4, 6, 7}, a, 6) 
({1, 2, 3}, z, 3) 

第一个字段是具有集合语义的包的并集。元组的第二个字段是组字段。第三个字段是袋子里的物品数量。

我围绕以下代码尝试了几种变体(将 SetUnion 替换为 Group/Distinct 等),但始终未能实现所需的行为:

DEFINE SetUnion        datafu.pig.bags.sets.SetUnion();

grouped = GROUP visitors by (FirstField);
merged = FOREACH grouped {
    VU = SetUnion(visitors.ThirdField);
    GENERATE 
        VU        as Vu,
        group     as FirstField,
        COUNT(VU) as Cnt;
    }
dump merged;

您能解释一下我错在哪里以及如何实现所需的行为吗?

【问题讨论】:

    标签: hadoop apache-pig


    【解决方案1】:

    我终于设法实现了想要的行为。我的解决方案的一个独立示例如下:

    数据文件:

    a       b       1
    a       b       2
    a       b       3
    a       b       4
    a       d       1
    a       b       3
    a       b       6
    a       e       7
    z       b       1
    z       b       2
    z       b       3
    

    代码:

    -- Prepare data
    in = LOAD 'data' USING PigStorage() 
            AS (One:chararray, Two:chararray, Id:long);
    
    grp = GROUP in by (One, Two);
    cnt = FOREACH grp {
            ids = DISTINCT in.Id;
            GENERATE
                    ids        as Ids,
                    group.One  as One,
                    group.Two  as Two,
                    COUNT(ids) as Count;
    }       
    
    -- Interesting code follows
    grp2 = GROUP cnt by One;
    cnt2 = FOREACH grp2 {
            ids = FOREACH cnt.Ids generate FLATTEN($0);
            GENERATE
                    ids  as Ids,
                    group      as One,
                    COUNT(ids) as Count;
    }               
    
    describe cnt2;
    dump grp2;
    dump cnt2;
    

    描述:

    Cnt: {Ids: {(Id: long)},One: chararray,Two: chararray,Count: long}
    

    grp2:

    (a,{({(1),(2),(3),(4),(6)},a,b,5),({(1)},a,d,1),({(7)},a,e,1)})
    (z,{({(1),(2),(3)},z,b,3)})
    

    cnt2:

    ({(1),(2),(3),(4),(6),(1),(7)},a,7)
    ({(1),(2),(3)},z,3)
    

    由于代码使用嵌套在 FOREACH 中的 FOREACH,因此需要 Pig > 10.0。

    由于可能存在更清洁的解决方案,因此我会让这个问题几天未解决。

    【讨论】:

      【解决方案2】:

      为此找到了一个更简单的解决方案。

      current_input = load '/idn/home/ksing143/tuple_related_data/tough_grouping.txt' 使用 PigStorage() AS (col1:chararray, col2:chararray, col3:int);

      /* 但我们不需要第 2 列。因此消除以避免混淆 */

      relevant_input = foreach current_input 生成 col1, col3;

      relevant_distinct = DISTINCT 相关输入;

      relevant_grouped = 按 col1 分组相关的_distinct;

      /* 这会给 */

      (a,{(a,1),(a,2),(a,3),(a,4),(a,6),(a,7)})

      (z,{(z,1),(z,2),(z,3)})

      relevant_grouped_advance = foreach related_grouped generate (relevant_distinct.col3) as col3, group, COUNT(relevant_distinct.col3) as count_val;

      /* 这会得到想要的结果 */

      ({(1),(2),(3),(4),(6),(7)},a,6)

      ({(1),(2),(3)},z,3)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-22
        • 1970-01-01
        • 2015-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-16
        • 1970-01-01
        相关资源
        最近更新 更多