Java 当第一个PCollection包含某个事件的时间帧和第二个时间戳时,如何连接两个PCollection?
我有一个用数据流编写的批处理管道。我想通过数据实现以下连接 我有两个电脑集。首先是代表会议:Java 当第一个PCollection包含某个事件的时间帧和第二个时间戳时,如何连接两个PCollection?,java,google-cloud-dataflow,apache-beam,Java,Google Cloud Dataflow,Apache Beam,我有一个用数据流编写的批处理管道。我想通过数据实现以下连接 我有两个电脑集。首先是代表会议: class Session{ String id long start; long stop; } 第二个是代表某个事件: class Event{ long timestamp; String id; } 我想加入这两个PCollection,并在最后加入类似于KV-的内容,即包含会话和相关事件列表的结构。如果事件的时间戳在一个会话(或多个会话)的时间范围
class Session{
String id
long start;
long stop;
}
第二个是代表某个事件:
class Event{
long timestamp;
String id;
}
我想加入这两个PCollection,并在最后加入类似于KV
-的内容,即包含会话和相关事件列表的结构。如果事件的时间戳在一个会话(或多个会话)的时间范围内,则应将其聚合并附加到该会话(或多个会话)上
实现这一目标的最佳方式是什么 考虑到这是一个批处理管道,我要做的是首先遍历所有可能的
会话
,构建一个列表并将其保存为PCollectionView
。然后,在分析每个事件时,我们可以检查它将落在哪个会话中
在我的测试中,我定义了类和构造函数,如下所示:
@DefaultCoder(AvroCoder.class)
公共静态课堂{
字符串id;
长起点;
长停;
公共会话(字符串id、长启动、长停止){
this.id=id;
this.start=start;
this.stop=停止;
}
公开会议(){
//仅用于序列化
}
}
@DefaultCoder(AvroCoder.class)
公共静态类事件{
字符串id;
长时间戳;
公共事件(字符串id,长时间戳){
this.id=id;
this.timestamp=时间戳;
}
公共活动(){
//仅用于序列化
}
}
我们将使用一些测试数据,例如:
//示例会话数据
最终列表sessionList=Arrays.asList(
新会话(“s1”、0升、100升),
新会话(“s2”,100L,200L),
新会话(“s3”、200L、300L)
);
//示例事件数据
最终列表eventList=Arrays.asList(
新事件(“e1”,20L),
新事件(“e2”,60L),
新活动(“e3”,120L),
新事件(“e4”,160L),
新事件(“e5”,210L),
新事件(“e6”,290L)
);
首先,我们将构建包含所有可能会话的PCollectionView
:
//从会话创建PCollectionView
最终PCollectionView会话PC=p
.apply(“创建会话”,Create.of(会话列表))
.apply(“另存为列表”,View.asList());
并且,对于每个事件
,我们将检查赋值fn
ParDo,如果事件
在其中,则会话
:
公共静态类AssignFn扩展DoFn{
最终PCollectionView会话PC;
公共分配fn(PCollectionView标记输入){
this.sessionPC=TagsideInput;
}
@过程元素
公共void processElement(ProcessContext c){
事件=c.元素();
//通过所有可能的会话获取边输入
列表会话=c.sideInput(sessionPC);
//这件事发生在哪里?
(届会:届会){
if(event.timestamp>=session.start&&event.timestamp