如何在列的子集上使用pig拉丁语执行distinct?

jslywgbw  于 2021-06-25  发布在  Pig
关注(0)|答案(6)|浏览(252)

我想对列的一个子集执行一个不同的操作。文档中说,这可以通过嵌套的foreach实现:
不能对字段子集使用distinct;为此,请使用foreach和嵌套块首先选择字段,然后应用distinct(请参见示例:嵌套块)。
对所有列执行不同的操作很简单:

A = LOAD 'data' AS (a1,a2,a3,a4);
A_unique = DISTINCT A;

假设我对跨a1、a2和a3执行distinct很感兴趣。有人能提供一个例子来说明如何按照文档中的建议使用嵌套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)
unftdfkk

unftdfkk1#

unique_A = FOREACH (GROUP A BY (a1, a2, a3)) {
    limit_a = LIMIT A 1;
    GENERATE FLATTEN(limit_a) AS (a1,a2,a3,a4);
};
ego6inou

ego6inou2#

我也希望这样做:“我想对列的子集执行一个不同的操作”。我的做法是:

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的示例;但这是一种在字段子集上执行distinct的方法。希望它能像我一样帮助到这里的人。

gpnt7bae

gpnt7bae3#

对于您指定的输入/输出,下面的工作。您可以更新您的测试向量,以澄清您需要什么不同于此。

A_unique = DISTINCT A;
hfwmuf9z

hfwmuf9z4#

公认的答案是一个很好的解决方案,但是,如果您想对输出中的字段重新排序(我最近不得不做的事情),这可能不起作用。这里有一个替代方案:

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 ;

当您对某些字段进行分组时,所选内容将在每个元组中为该组提供唯一的值。

b09cbbtk

b09cbbtk5#

这里有两种可能的解决方案,还有其他好的方法吗?
解决方案1(使用限值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);
};
ljsrvy3e

ljsrvy3e6#

将所有其他列分组,只将感兴趣的列投影到一个包中,然后使用 FLATTEN 再次展开:

A_unique =
    FOREACH (GROUP A BY a4) {
        b = A.(a1,a2,a3);
        s = DISTINCT b;
        GENERATE FLATTEN(s), group AS a4;
    };

相关问题