Je souhaite effectuer une opération DISTINCT sur un sous-ensemble des colonnes. La documentation indique que cela est possible avec un foreach imbriqué:
Vous ne pouvez pas utiliser DISTINCT sur un sous-ensemble de champs; Pour ce faire, utilisez FOREACH et un bloc imbriqué pour sélectionner d'abord les champs, puis appliquez DISTINCT (voir Exemple: Bloc imbriqué).
Il est simple d’effectuer une opération DISTINCT sur toutes les colonnes:
A = LOAD 'data' AS (a1,a2,a3,a4);
A_unique = DISTINCT A;
Disons que je suis intéressé par l'exécution de la distinction entre a1, a2 et a3. Quelqu'un peut-il fournir un exemple montrant comment effectuer cette opération avec une forfor imbriquée comme suggéré dans la documentation?
Voici un exemple d'entrée et de sortie attendue:
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)
Regroupez sur toutes les autres colonnes, projetez uniquement les colonnes d'intérêt dans un sac, puis utilisez FLATTEN
pour les développer à nouveau:
A_unique =
FOREACH (GROUP A BY a4) {
b = A.(a1,a2,a3);
s = DISTINCT b;
GENERATE FLATTEN(s), group AS a4;
};
La réponse acceptée est une excellente solution, mais si vous souhaitez réorganiser les champs de la sortie (ce que j'ai dû faire récemment), cela pourrait ne pas fonctionner. Voici une alternative:
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 ;
Lorsque vous groupez sur certains champs, la sélection aurait des valeurs uniques pour le groupe dans chaque tuple.
Pour votre entrée/sortie spécifiée, les éléments suivants fonctionnent. Vous pouvez mettre à jour vos vecteurs de test pour clarifier ce dont vous avez besoin et qui est différent de celui-ci.
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);
};
Voici 2 solutions possibles, existe-t-il d'autres bonnes approches?
Solution 1 (avec 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);
};
Solution 2 (en utilisant 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);
};