使用 Pig Latin - Hadoop 将元组插入内袋

Inserting tuples inside an inner bag using Pig Latin - Hadoop

我正在尝试使用 Pig Latin 创建以下格式的关系:

userid, day, {(pid,fulldate, x,y),(pid,fulldate, x,y), ...}

关系描述:每个用户(userid)在每一天(day)购买了多个产品(pid)

我正在将数据加载到:

A= LOAD '**from a HDFS URL**' AS (pid: chararray,userid: 
chararray,day:int,fulldate: chararray,x: chararray,y:chararray);
B= GROUP A BY (userid, day);
Describe B;

B: {group: (userid: chararray,day: int),A: {(pid: chararray,day: int,fulldate: chararray,x: chararray,userid: chararray,y: chararray)}}

C= FOREACH B FLATTEN(B) AS (userid,day), .pid, .fulldate,.x,.y;
Describe C;

C: {userid: chararray,day: int,{(pid: chararray)}},{(fulldate: chararray)},{(x: chararray)},{(y: chararray)}}

Describe C的结果不是我想要的格式!我做错了什么?

我的理解是 B 几乎就是你要找的,只是你希望包含 useridday 的元组被压平,而你只想pidfulldatexy 出现在包中。

首先,您要展平包含字段 useridday 的元组 group,而不是包含多个元组的包 A。展平 group 取消元组的嵌套,它的每一行只有一组唯一值,而展平包 A 将有效地取消分组您之前的 GROUP BY 语句,因为包中的值 A 不是唯一的。所以第一部分应该是 C = FOREACH B GENERATE FLATTEN(group) AS (userid, day);

接下来,您想将 pidfulldatexy 保留在每个记录的单独元组中,但是您选择它们​​的方式本质上是将所有 pid 值组成一个包,将所有 fulldate 值组成一个包,等等。相反,尝试以一种使元组嵌套在包中的方式选择这些字段:

C = FOREACH B GENERATE 
    FLATTEN(group) AS (userid, day), 
    A.(pid, fulldate, x, y) AS A;

你在 GROUP BY 部分之前是正确的。然而在那之后你试图做一些混乱的事情。我实际上不确定您的别名 C 发生了什么。要获得您正在寻找的格式,您将需要一个嵌套的 foreach。

C = FOREACH B {
         data = A.pid, A.fulldate, A.x, A.y;
         GENERATE FLATTEN(group), data;
    }

这允许 C 为每个 (userid, day) 和包中所有对应的 (pid,fulldate, x, y) 元组有一个记录。 您可以在此处阅读有关嵌套 foreach 的更多信息:https://www.safaribooksonline.com/library/view/programming-pig/9781449317881/ch06.html(在 link 中搜索嵌套 foreach)。