web-dev-qa-db-fra.com

Comment effectuer un DISTINCT en Pig Latin sur un sous-ensemble de colonnes?

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)
12
Freerobots

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;
    };
19
reo katoa

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. 

2
Prasoon Joshi

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;
1
one2go
unique_A = FOREACH (GROUP A BY (a1, a2, a3)) {
    limit_a = LIMIT A 1;
    GENERATE FLATTEN(limit_a) AS (a1,a2,a3,a4);
};
0
costa xu

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);
};
0
Freerobots