Google compute engine 如何在谷歌云数据流上使用另一个管道值搜索管道

Google compute engine 如何在谷歌云数据流上使用另一个管道值搜索管道,google-compute-engine,google-cloud-dataflow,Google Compute Engine,Google Cloud Dataflow,我想用google cloud dataflow从流数据中搜索包含指定单词的文本 具体来说,我将处理以下两个流 流A:流的元素是“字” 流B:流的元素是“文本”。每一个文本都由“单词”组成。此文本可能在流A上有“word” 许多“文本”经常流入流B。另一方面,“单词”偶尔流入一条小溪 当“单词”流入流A时,我想搜索包含“单词”的“文本”,并在5分钟前流入流B 范例 time stream A : stream B 00:01 - this is an apple 00:0

我想用google cloud dataflow从流数据中搜索包含指定单词的文本

具体来说,我将处理以下两个流

  • 流A:流的元素是“字”
  • 流B:流的元素是“文本”。每一个文本都由“单词”组成。此文本可能在流A上有“word”
许多“文本”经常流入流B。另一方面,“单词”偶尔流入一条小溪

当“单词”流入流A时,我想搜索包含“单词”的“文本”,并在5分钟前流入流B

范例

time  stream A : stream B
00:01 -          this is an apple
00:02 -          this is an orange
00:03 -          I have an apple
00:04 apple                        <= "this is an apple" and "I have an apple" are found
00:05 this                         <= "this is an apple" and "this is an orange" are found
时间流A:流B
00:01-这是一个苹果
00:02-这是一个橘子
00:03-我有一个苹果

00:04苹果如果我正确理解你的问题,有多种方法可以实现你想要的东西。我将描述两种变体

我的示例代码中的基本思想是使用内部联接和五分钟的滑动窗口。根据数据大小,可以使用
ParDo
侧输入或
CoGroupByKey
实现连接

以下是如何设置输入和窗口:

PCollection streamA=。。。;
PCollection streamB=。。。;
PCollection windowedStreamA=streamA.apply(
开窗(
滑动窗口。的(持续时间。标准分钟(5))。每(…);
PCollection windowedStreamB=streamB.apply(
开窗(
滑动窗口。的(持续时间。标准分钟(5))。每(…);
您可能需要调整窗口或时段的大小,以满足您的规格和性能需求

下面是如何使用侧面输入进行连接的示意图。对于
streamA
的每个元素,这将在
streamB
的整个五分钟窗口内迭代,因此如果窗口变大,性能将受到影响

PCollectionView streamBview=streamB.apply(View.asIterable());
PCollection matches=windowedStreamA.apply(
(新DoFn()的副部长{
@重写无效的processElement(ProcessContext上下文){
for(字符串文本:context.sideInput()){
if(拆分(text).contains(context.element())){
输出(文本);
}
}
}
});
下面是如何使用
CoGroupByKey
进行此操作的示意图,方法是预拆分文本并将每个关键字与包含该关键字的行连接起来。SDK附带的
TfIdf
示例中也有类似的逻辑

PCollection keyedstreeama=windowedStreamA.apply(
地图元素
.via(字->千伏(字,空))
.withOutputType(新类型描述符(){}));
PCollection keyedStreamB=windowedStreamB.apply(
平面映射元素
.via(text->split(text).forEach(word-->KV.of(word,text))
.withOutputType(新类型描述符(){}));
TupleTag tagA=新的TupleTag(){};
TupleTag tagB=新的TupleTag(){};
KeyedPCollectionTuple coGbkInput=KeyedPCollectionTuple
.of(塔加,键流a)
.和(tagB,keyedStreamB);
PCollection matches=cogbk输入
.apply(CoGroupByKey.create())
.应用(FlatMapElements)
.via(结果->结果.getAll(tagB))
.withOutputType(新类型描述符());

最好的方法取决于您的数据。如果您能在过去五分钟内获得更多的匹配,您可以通过扩大滑动窗口并延长时间来调整windows中的数据复制量。您还可以在生成输出时使用触发器进行调整。

如果我正确理解您的问题,则会出现以下问题:有多种方法可以实现你想要的东西。我将描述两种不同的方法

我的示例代码中的基本思想是使用内部联接和五分钟的
SlidingWindows
。您可以使用
ParDo
侧输入或
CoGroupByKey
实现联接,具体取决于您的数据大小

以下是如何设置输入和窗口:

PCollection streamA=。。。;
PCollection streamB=。。。;
PCollection windowedStreamA=streamA.apply(
开窗(
滑动窗口。的(持续时间。标准分钟(5))。每(…);
PCollection windowedStreamB=streamB.apply(
开窗(
滑动窗口。的(持续时间。标准分钟(5))。每(…);
您可能需要调整窗口或时段的大小,以满足您的规格和性能需求

下面是如何使用侧面输入进行连接的示意图。这将在
streamB
的整个五分钟窗口中迭代
streamA
的每个元素,因此如果窗口变大,性能将受到影响

PCollectionView streamBview=streamB.apply(View.asIterable());
PCollection matches=windowedStreamA.apply(
(新DoFn()的副部长{
@重写无效的processElement(ProcessContext上下文){
for(字符串文本:context.sideInput()){
if(拆分(text).contains(context.element())){
输出(文本);
}
}
}
});
下面是如何使用
CoGroupByKey
进行此操作的示意图,方法是预拆分文本并将每个关键字与包含该关键字的行连接起来。SDK附带的
TfIdf
示例中也有类似的逻辑

PCollection keyedstreeama=windowedStreamA.apply(
地图元素
.via(字->千伏(字,空))
.withOutputType(新类型描述符(){}));
PCollection keyedStreamB=windowedStreamB.apply(
平面映射元素
.via(text->split(text).forEach(word-->KV.of(word,text))
.withOutputType(新类型描述符(){}));
TupleTag tagA=新的TupleTag(){};
TupleTag tagB=新的TupleTag(){};
KeyedPCollectionTuple coGbkInput=KeyedPCollectionTuple
.of(塔加,键流a)
.和(tagB,keyedStreamB);
PCollection matches=cogbk输入
.apply(CoGroupByKey.create())
.应用(FlatMapElemen)