在非轻量级DoFn中访问侧输入

时间:2017-08-02 14:01:10

标签: google-cloud-dataflow apache-beam

如果我的类扩展了DoFn,如何访问侧输入的元素?

例如:

假设我有一个ParDo变换,如:

PCollection<String> data = myData.apply("Get data",
    ParDo.of(new MyClass()).withSideInputs(myDataView));

我有一节课: -

static class MyClass extends DoFn<String,String>
{
    //How to access side input here
}

c.sideInput()在这种情况下不起作用。

感谢。

2 个答案:

答案 0 :(得分:5)

在这种情况下,问题是DoFn中的processElement方法无法访问main方法中的PCollectionView实例。

您可以将PCollectionView传递给构造函数中的DoFn:

class MyClass extends DoFn<String,String>
{
    private final PCollectionView<..> mySideInput;

    public MyClass(PCollectionView<..> mySideInput) {
        // List, or Map or anything:
        this.mySideInput = mySideInput;
    }

    @ProcessElement
    public void processElement(ProcessContext c) throws IOException
    {
        // List or Map or any type you need:
        List<..> sideInputList = c.sideInput(mySideInput);
    }
}

对此的解释是,当您使用匿名DoFn时,进程方法有一个闭包,可以访问包含DoFn的范围内的所有对象(其中包括PCollectionView)。当您不使用匿名DoFn时,没有闭包,您需要另一种传递PCollectionView的方法。

答案 1 :(得分:1)

所以尽管上面的答案是正确的,但它仍然有点不完整。

因此,一旦完成上述答案,您需要像这样执行您的管道:

    p.apply(ParDo.of(new MyClass(mySideInput)).withSideInputs(mySideInput));