3

私はを使用して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) 

最初のフィールドは、設定されたセマンティックを持つバッグの和集合です。タプルの2番目のフィールドは、グループフィールドです。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;

私が間違っているところと、望ましい動作を実装する方法を説明できますか?

4

2 に答える 2

4

私はついに望みの行動を達成することができました。私のソリューションの自己完結型の例は次のとおりです。

データファイル:

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が必要です。

よりクリーンな解決策がおそらく存在するので、私は質問を数日間未解決のままにしておきます。

于 2013-03-27T14:57:49.910 に答える
0

このためのより簡単な解決策を見つけました。

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

/ *ただし、列2は必要ありません。したがって、混乱を避けるために削除します* /

related_input = foreach current_input generate col1、col3;

related_distinct = DISTINCT related_input;

related_grouped=col1によるグループrelevant_distinct;

/*これは*/を与えます

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

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

related_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)

于 2016-12-20T07:28:59.360 に答える