::
中.
和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::z
或B.z
传递给SUM
而不是B?z
?
答案 0 :(得分:5)
在Pig中,::
在可能产生命名冲突的操作之后用作消歧工具。值得注意的是,JOIN
,CROSS
和FLATTEN
会发生这种情况。考虑两个关系,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
的特定字段。