列のサブセットでDISTINCT操作を実行したいと思います。 documentation は、これがネストされたforeachで可能であると述べています:
フィールドのサブセットでDISTINCTを使用することはできません。これを行うには、FOREACHとネストされたブロックを使用して、最初にフィールドを選択し、次にDISTINCTを適用します(例:ネストされたブロックを参照)。
すべての列でDISTINCT操作を実行するのは簡単です。
A = LOAD 'data' AS (a1,a2,a3,a4);
A_unique = DISTINCT A;
A1、a2、およびa3を区別して実行することに興味があるとしましょう。ドキュメントで提案されているように、ネストされたforeachでこの操作を実行する方法を示す例を誰かが提供できますか?
入力と期待される出力の例を次に示します。
A = LOAD 'data' AS(a1,a2,a3,a4);
DUMP A;
(1 2 3 4)
(1 2 3 4)
(1 2 3 5)
(1 2 4 4)
-- insert DISTINCT operation on a1,a2,a3 here:
-- ...
DUMP A_unique;
(1 2 3 4)
(1 2 4 4)
他のすべての列をグループ化し、関心のある列のみをバッグに投影し、FLATTEN
を使用してそれらを再度展開します。
A_unique =
FOREACH (GROUP A BY a4) {
b = A.(a1,a2,a3);
s = DISTINCT b;
GENERATE FLATTEN(s), group AS a4;
};
受け入れられた答えは1つの素晴らしい解決策ですが、出力のフィールドを並べ替えたい場合(最近私がしなければならなかったもの)、これは機能しない可能性があります。ここに代替があります:
A = LOAD '$input' AS (f1, f2, f3, f4, f5);
GP = GROUP A BY (f1, f2, f3);
OUTPUT = FOREACH GP GENERATE
group.f1, group.f2, f4, f5, group.f3 ;
特定のフィールドでグループ化すると、選択は各タプルのグループに対して一意の値を持ちます。
指定した入出力に対して、次のように動作します。テストベクタを更新して、これとは異なる必要なものを明確にすることができます。
A_unique = DISTINCT A;
unique_A = FOREACH (GROUP A BY (a1, a2, a3)) {
limit_a = LIMIT A 1;
GENERATE FLATTEN(limit_a) AS (a1,a2,a3,a4);
};
私は同じことをしたいと思っていました:「列のサブセットでDISTINCT操作を実行したい」。私がそれをした方法は:
A = LOAD 'data' AS(a1,a2,a3,a4);
interested_fields = FOREACH A GENERATE a1,a2,a3;
distinct_fields= DISTINCT interested_fields;
final_answer = FOREACH distinct_fields GENERATE FLATTEN($0);
ドキュメントで提案されているように、ネストされたforeachを実行する方法の例ではないことはわかっています。しかし、これはフィールドのサブセットを区別する方法です。それが私と同じようにここに来るすべての人に役立つことを願っています。
ここに2つの可能な解決策がありますが、他に良いアプローチはありますか?
ソリューション1(LIMIT 1を使用):
A = LOAD 'test_data' AS (a1,a2,a3,a4);
-- Combine the columns that I want to perform the distinct across into a Tuple
A2 = FOREACH A GENERATE TOTUPLE(a1,a2,a3) AS combined, a4 as a4
-- Group by the combined column
grouped_by_a4 = GROUP A2 BY combined;
grouped_and_distinct = FOREACH grouped_by_a4 {
single = LIMIT A2 1;
GENERATE FLATTEN(single);
};
ソリューション2(DISTINCTを使用):
A = LOAD 'test_data' AS (a1,a2,a3,a4);
-- Combine the columns that I want to perform the distinct across into a Tuple
A2 = FOREACH A GENERATE TOTUPLE(a1,a2,a3) AS combined, a4 as a4
-- Group by the other columns (those I don't want the distinct applied to)
grouped_by_a4 = GROUP A2 BY a4;
-- Perform the distinct on a projection of combined and flatten
grouped_and_distinct = FOREACH grouped_by_a4 {
combined_unique = DISTINCT A2.combined;
GENERATE FLATTEN(combined_unique);
};