Apache Beam TextIO.ReadAll如何发出KeyValue而不是Pcollection的字符串

时间:2018-12-20 21:43:56

标签: java apache-beam

管道从读取PUBSUBIo开始。 PubSub IO内的消息是GCS文件路径。我知道我可以使用ReadAll()从每条路径发出线。但是,它不符合我的目的(有关文件路径的信息丢失了)。我需要发出的是KV<'Filepath','Lines inside files'>

PubSUB消息看起来像

Message1 -> gs://folder1/Topic1/topicfile1.gz
Message2 -> gs://folder1/Topic2/topicfile2.gz

假设文件内容如下所示

topicfile1.gz
{
topic1.line1
topic1.line2
}

topicfile2.gz
{
topic2.line1
topic2.line2
}

我期望的是像下面这样的收藏集

{KV<'gs://folder1/Topic1/topicfile1.gz','topic1.line1'>}
{KV<'gs://folder1/Topic1/topicfile1.gz','topic1.line2'>}
{KV<'gs://folder1/Topic2/topicfile2.gz','topic2.line1'>}
{KV<'gs://folder1/Topic2/topicfile2.gz','topic2.line2'>}

我找不到从ParDo函数内部的路径读取文件以将路径映射到行的方法。

希望这很清楚。

1 个答案:

答案 0 :(得分:0)

如果我正确理解了这个问题,我认为TextIO内的功能不被支持。

详细信息

当您应用readAll()之类的转换时,从IO获取初始文件路径与最后从所有文件发出所有行之间需要涉及几个步骤。

例如,逻辑in TextIO

  • 它接受PCollection个文件路径(或路径模式);
  • 它应用FileIO.matchAll()将路径模式的PCollection转换成描述这些路径的PCollection对象的MatchResult.Metadata
  • 然后应用FileIO.readMatches()将元数据对象转换为描述特定文件的ReadableFile对象;
  • 最后,它应用TextIO.readFiles()并接受ReadableFile并输出该文件中的所有字符串;
    • 在最后一步,您想要向输出添加文件路径,以便知道哪个字符串来自哪个文件。如果可以选择更改最后一个步骤以发出KV<ReadableFile, String>而不是字符串,那么这将有帮助,这样您就可以使用ReadableFile.metadata访问文件路径。

看看这段代码,看来从文件中发出原始行是目前唯一支持的使用TextIO的处理方式。

解决方法

最简单的方法可能是编写自己的PTransform,类似于TextIO.ReadAll。这样会起作用:

高级:

  • 创建和自定义自己的版本TextIO.ReadAll;
  • ReadAllViaFileBasedSource中的
  • 更改ReadAllViaFileBasedSource的版本以发出所需的内容;
  • 使用此TextIO.ReadAll的自定义版本,该版本使用发出正确内容的自定义版本ReadAllViaFileBasedSource

稍微详细一点: