Pig 10.0 - 将元组分组并在 foreach 中合并包
Posted
技术标签:
【中文标题】Pig 10.0 - 将元组分组并在 foreach 中合并包【英文标题】:Pig 10.0 - group the tuples and merge bags in a foreach 【发布时间】:2013-03-27 14:07:13 【问题描述】:我正在使用Pig 10.0
。我想在 foreach 中合并包。假设我有以下visitors
别名:
(a, b, 1, 2, 3, 4),
(a, d, 1, 3, 6),
(a, e, 7),
(z, b, 1, 2, 3)
我想对第一个字段上的元组进行分组,并将包与一组语义合并以获得以下元组:
(1, 2, 3, 4, 6, 7, a, 6)
(1, 2, 3, z, 3)
第一个字段是具有集合语义的包的并集。元组的第二个字段是组字段。第三个字段是袋子里的物品数量。
我围绕以下代码尝试了几种变体(将 SetUnion 替换为 Group/Distinct 等),但始终未能实现所需的行为:
DEFINE SetUnion datafu.pig.bags.sets.SetUnion();
grouped = GROUP visitors by (FirstField);
merged = FOREACH grouped
VU = SetUnion(visitors.ThirdField);
GENERATE
VU as Vu,
group as FirstField,
COUNT(VU) as Cnt;
dump merged;
您能解释一下我错在哪里以及如何实现所需的行为吗?
【问题讨论】:
【参考方案1】:我终于设法实现了想要的行为。我的解决方案的一个独立示例如下:
数据文件:
a b 1
a b 2
a b 3
a b 4
a d 1
a b 3
a b 6
a e 7
z b 1
z b 2
z b 3
代码:
-- Prepare data
in = LOAD 'data' USING PigStorage()
AS (One:chararray, Two:chararray, Id:long);
grp = GROUP in by (One, Two);
cnt = FOREACH grp
ids = DISTINCT in.Id;
GENERATE
ids as Ids,
group.One as One,
group.Two as Two,
COUNT(ids) as Count;
-- Interesting code follows
grp2 = GROUP cnt by One;
cnt2 = FOREACH grp2
ids = FOREACH cnt.Ids generate FLATTEN($0);
GENERATE
ids as Ids,
group as One,
COUNT(ids) as Count;
describe cnt2;
dump grp2;
dump cnt2;
描述:
Cnt: Ids: (Id: long),One: chararray,Two: chararray,Count: long
grp2:
(a,((1),(2),(3),(4),(6),a,b,5),((1),a,d,1),((7),a,e,1))
(z,((1),(2),(3),z,b,3))
cnt2:
((1),(2),(3),(4),(6),(1),(7),a,7)
((1),(2),(3),z,3)
由于代码使用嵌套在 FOREACH 中的 FOREACH,因此需要 Pig > 10.0。
由于可能存在更清洁的解决方案,因此我会让这个问题几天未解决。
【讨论】:
【参考方案2】:为此找到了一个更简单的解决方案。
current_input = load '/idn/home/ksing143/tuple_related_data/tough_grouping.txt' 使用 PigStorage() AS (col1:chararray, col2:chararray, col3:int);
/* 但我们不需要第 2 列。因此消除以避免混淆 */
relevant_input = foreach current_input 生成 col1, col3;
relevant_distinct = DISTINCT 相关输入;
relevant_grouped = 按 col1 分组相关的_distinct;
/* 这会给 */
(a,(a,1),(a,2),(a,3),(a,4),(a,6),(a,7))
(z,(z,1),(z,2),(z,3))
relevant_grouped_advance = foreach related_grouped generate (relevant_distinct.col3) as col3, group, COUNT(relevant_distinct.col3) as count_val;
/* 这会得到想要的结果 */
((1),(2),(3),(4),(6),(7),a,6)
((1),(2),(3),z,3)
【讨论】:
以上是关于Pig 10.0 - 将元组分组并在 foreach 中合并包的主要内容,如果未能解决你的问题,请参考以下文章