猪的`::`和`.`有什么区别?

时间:2013-12-10 18:04:02

标签: apache-pig

::.pig之间的区别是什么?

我何时使用一个与另一个?

例如,我知道当两个别名中都存在字段时,::需要join

A = foreach (join B by (x), C by (y)) generate B::y as b_y, C::y as c_y;

我在访问.字段时需要group

A = foreach (group B by (x,y)) generate group.x as x, group.y as y, SUM(B?z) as z;

但是,我是否将B::zB.z传递给SUM而不是B?z

2 个答案:

答案 0 :(得分:5)

在Pig中,::在可能产生命名冲突的操作之后用作消歧工具。值得注意的是,JOINCROSSFLATTEN会发生这种情况。考虑两个关系,A:{(id:int, name:chararray)}B:{(id:int, location:chararray)}。如果您想将名称与位置相关联,那么您自然会这样做:

C = JOIN A BY id, B BY id;

如果没有消歧操作符,您的架构将是

C:{(id:int, name:chararray, id:int, location:chararray)}

现在你无法分辨id指的是哪个字段。为避免这种情况,猪会改为

C:{(A::id:int, A::name:chararray, B::id:int, B::location:chararray)}

同样地,你可以FLATTEN两个包的元组具有相同名称的字段,它们也会发生碰撞。因此在这种情况下也使用相同的运算符。如果没有这样的冲突,您不需要使用全名:name在这里是明确的。为了简化C,您可以这样做:

D = FOREACH C GENERATE A::id, name, location;

相比之下,.运算符会从包和元组中投射字段。如果您的行李b包含架构{(x:int, y:int, z:int)},则投影b.y会生成一个仅包含指定字段的行李:{(y:int)}。您可以使用括号一次投影多个字段:b.(y,z)会产生{(y:int, z:int)}

与元组一起使用时,结果是仅包含指定字段的元组。如果元组t包含架构(x:int, y:int, z:int),则t.x为元组(x:int),而t.(y,z)为元组(y:int, z:int)


关于SUM的具体问题,请注意SUM以及其他摘要统计信息UDF,并将其作为参数。因此,您需要创建一个包,每个元组只需要一个字段。使用投影运算符.B.z

答案 1 :(得分:1)

IIRC你在一些陈述之后得到::副作用。你不能打扰它,除非(如你所提到的)在两个不同的前缀中存在一个名称。

.的不同之处在于您要进入结构内部。 group.x as x, group.y as y相当于FLATTEN(group)

SUM(B?z) - 在这里您应该SUM(B.z),指明您需要SUM的特定字段。