我在Google云端存储中有以下内容
Advertiser | Event
__________________
100 | Click
101 | Impression
100 | Impression
100 | Impression
101 | Impression
我的管道输出应该是
Advertiser | Clicks | Impressions
100 | 1 | 2
101 | 0 | 2
首先我使用groupByKey,输出就像
100点击,印象,印象
101印象,印象
现在可以计算KV中的值吗?
目前,我只是使用比较字符串来计算点击次数和展示次数。
可以在这里使用计数变换吗?
或者我们在这里使用其他任何变换吗?
或者我的方式是唯一的方式?
谢谢, 萨姆。
答案 0 :(得分:0)
我假设您的输入信息为PCollection<KV<Long, EventType>> input
,其中Long
是广告客户ID,EventType
是enum { CLICK, IMPRESSION, possibly something else }
。
我还假设您希望输出为PCollection&gt;其中AdvertiserStats是一个字段为“numClicks”,“numImpressions”的类。
在这种情况下,实现目标的一种方法是使用Combine - input.apply(Combine.<Long, AdvertiserStats>perKey(new ComputeAdvertiserStatsFn()))
,其中ComputeAdvertiserStatsFn
的定义如下:
public class ComputeAdvertiserStatsFn
extends CombineFn<EventType, AdvertiserStats, AdvertiserStats> {
public AdvertiserStats createAccumulator() { return new AdvertiserStats(); }
public void addInput(AdvertiserStats stats, EventType input) {
switch (input) {
case CLICK: stats.numClicks++; break;
case IMPRESSION: stats.numImpressions++; break;
default: (depending on your application?)
}
}
public AdvertiserStats mergeAccumulators(Iterable<AdvertiserStats> stats) {
AdvertiserStats merged = createAccumulator();
for (AdvertiserStats item : stats) {
merged.numClicks += item.numClicks;
merged.numImpressions += item.numImpressions;
}
return merged;
}
public AdvertiserStats extractOutput(AdvertiserStats stats) { return stats; }
}
这应该表现得非常好,因为大多数分组和计数都会在本地进行。
目前,AFAIK,没有PTransform
可以为您完成ComputeAdvertiserStatsFn
的工作。我认为理想的界面看起来像input.apply(Combine.perKey(Count.perElement()))
,但它不适用于当前定义的方式。