将许多键/值元组组合并压平成猪的单个元组

时间:2013-12-10 19:53:53

标签: tuples apache-pig

我正在使用Pig 0.8.1。我对Pig有点新,但我知道必须有一个合理且可重复使用的解决方案,以便我如何使用我的元组。我有以下格式(类似于三元组):

Schema: (uuid, key, val)

Data:
(id1, 'name', 'Corey')
(id1, 'location', 'USA')
(id1, 'carsOwned', 5)
(id2, 'name', 'Paul')
(id2, 'location', 'CANADA')
(id2, 'carsOwned', 10)

我在三元组中表示这些数据的原因是因为它可能具有多值键,因此将数据推送到地图是不可能的。

我需要做的是找到拥有前10辆车的人的ID,名称和位置。如果我的输出格式按降序排序,我会喜欢它:

Schema: (uuid, name, location, carsOwned)

Data:
(id2, 'Paul', 'CANADA', 10)
(id1, 'Corey', 'USA', 5)

我尝试将输入过滤为3个不同的别名(其中一个是key =='name',一个是key =='location',另一个是key =='carsOwned')所以我可以使用JOIN并带来它们回到一个元组,但看起来Pig最终从inputFormat加载3次而不是一次。也许我做错了?

我也尝试按ID进行分组,但是我似乎找不到合理的方法来处理实际三键/值的包,因为它们都具有完全相同的模式。

我真正想要的是按id字段分组,然后展平每个键,但将别名重命名为键的实际名称。

有什么想法吗?提前谢谢!

1 个答案:

答案 0 :(得分:2)

这个解决方案有点草率,因为你的数据没有以Pig真正设置的方式组织 - 也就是说,概念上每个id都显示为一个行键,其中的字段以你在第二个中所拥有的字段命名柱。但只要您的数据合理,这仍然可以完成。如果您错误地使用具有相同ID和字段名称但具有不同值的多行,这将变得复杂。

使用嵌套的foreach选择您感兴趣的三个字段的值。

keyedByID =
    /* Gather the rows by ID, then process each one in turn */
    FOREACH (GROUP Data BY id) {
        /* Pull out the fields you want. If you have duplicate rows,
           you'll need to use a LIMIT statement to ensure just a single record */
        name = FILTER Data BY field == 'name';
        location = FILTER Data BY field == 'location';
        carsOwned = FILTER Data BY field == 'carsOwned';
    GENERATE
        /* Output each field you want. You'll need to use FLATTEN since
           the things created above in the nested foreach are bags. */
        group AS id,
        FLATTEN(name) AS name,
        FLATTEN(locatioN) AS location,
        FLATTEN(carsOwned) AS carsOwned;
    };

现在你已经建立了一个将ID的所有信息放在一行上的关系,你可以随心所欲地使用它。例如,你说想要拔出前10名车主:

ordered = ORDER keyedByID BY carsOwned DESC;
top10 = LIMIT ordered 10;