如何计算每个窗口的元素

时间:2018-07-09 04:24:33

标签: google-cloud-dataflow apache-beam

我正在尝试解决看似简单的问题-计算每个窗口的PCollection中有多少个元素。我需要它在写入时传递给.withSharding()函数,以创建与将要写入的文件一样多的碎片。

我试图做:

FileIO.writeDynamic<Long, E>()
    .withDestinationCoder(AvroCoder.of(Long::class.java))
    .by { e -> e.key }
    .via(Contextful.fn(MySerFunction()))
    .withNaming({ key -> MyFileNaming() })
    .withSharding(ShardingFn())
    .to("gs://some-output")

class ShardingFn : PTransform<PCollection<E>>, PCollectionView<Int>>() {
    override fun expand(input: PCollection<E>): PCollectionView<Int> {

        val keys: PCollection<Long> = input.apply(Keys.create())

        // This only works with GlobalWindowing, how to count per window?
        val count: PCollection<Long> = keys.apply(Count.globally())

        val int: PCollection<Int> = count.apply(MapElements.via(Long2Int))
        return int.apply(View.asSingleton())
    }

但是,这仅在我具有全局窗口(也称为“批处理模式”)的情况下有效,否则Count.globally()会引发异常。

也许我写错了,但是如果由于其他原因我想对每个窗口的元素进行计数,该怎么做呢?

2 个答案:

答案 0 :(得分:2)

在您的情况下,可以使用Combine.globally(Count.<T>combineFn()).withoutDefaults()代替Count.globally()。也可以在Javadoc中找到:https://beam.apache.org/documentation/sdks/javadoc/2.5.0/org/apache/beam/sdk/transforms/Count.html#globally--

答案 1 :(得分:1)

要计算每个窗口的数据,您必须使用时间戳(如果数据中没有时间戳,则添加一个),然后对其进行计数。我建议您仔细阅读此example,因为它详细说明了如何操作。