Java Apache-Flink如何进行映射&;将备用密钥与主键匹配到一个密钥流
我想要一个更简单、更好、更优雅的方法来解决下面的问题。我还没有看到关于这个主题的任何文档,我确信我目前的方法有一些瓶颈,谢谢 我有一个将Json映射到POJO的流Java Apache-Flink如何进行映射&;将备用密钥与主键匹配到一个密钥流,java,apache-flink,flink-streaming,Java,Apache Flink,Flink Streaming,我想要一个更简单、更好、更优雅的方法来解决下面的问题。我还没有看到关于这个主题的任何文档,我确信我目前的方法有一些瓶颈,谢谢 我有一个将Json映射到POJO的流 DataStream<MYPOJO> stream = env. addSource( <<kafkaSource>>).map(new EventToPOJO()); DataStream-stream=env。 addSource().map(新的EventToPOJ
DataStream<MYPOJO> stream = env.
addSource( <<kafkaSource>>).map(new EventToPOJO());
DataStream-stream=env。
addSource().map(新的EventToPOJO());
POJO的一些字段将有一个填充的主键,一些字段将有一个填充的备用键,一些字段将同时具有这两个键。我在Flink文档中找到的唯一一个使用两个键的示例是,对复合键使用一个键选择器,但对备用键不使用任何选项
我目前的做法如下:
DataStream primaryKey=stream.flatMap(新的RichFlatmap函数(){
@凌驾
公共void flatMap(MyPOJO MyPOJO,收集器收集器)引发异常{
if(mypojo.PrimaryKey()!=null){
collector.collect(MyPOJO);
}
}
});
DataStream alternateKey=stream.flatMap(新的RichFlatMapFunction(){
@凌驾
公共void flatMap(MyPOJO MyPOJO,收集器收集器)引发异常{
if(mypojo.getAlternateKey()!=null){
collector.collect(mypojo);
}
}
});
DataStream both=stream.flatMap(新的RichFlatmap函数(){
@凌驾
公共void flatMap(MyPOJO MyPOJO,收集器收集器)引发异常{
if(mypojo.getAlternateKey()!=null&&mypojo.getPrimaryKey()!=null){
collector.collect(mypojo);
}
}
});
//加入他们
两者。加入(交替)
.where(MyPOJO::getAlternateKey)
.equalTo(MyPOJO::getAlternateKey)
.window(TumblingEventTimeWindows.of(时间毫秒(1)))
.apply(新函数(){
@凌驾
公共状态对象联接(MyPOJO MyPOJO,MyPOJO mypojo2)引发异常{
//一些连接逻辑以保持两种状态
返回状态对象2;
}
});
::对主键流重复此操作。。。
//最后的凯比
keyBy(MyPOJO::getPrimaryKey)
我相信我也可以使用一个过滤函数来实现这3个流,但我不想一开始就分裂成3个流,请不要,为了可读性,我简化了上面的内容,所以请不要介意您可能发现的任何语法错误。您应该实现一个包含主键和辅键的自定义POJO。它需要有
equals()
和hashCode()
方法,当两条记录相等时,这些方法实现所需的逻辑(*)。看见
更多关于你为什么要这样做的细节
添加一个MyPOJO.getJoiningKey()
返回此自定义POJO
然后根据.where(r->r.getJoiningKey()).equals(r->r.getJoiningKey())
进行一次连接
(*)我仍然不确定您希望您的逻辑是什么。例如,如果左侧主键和辅键不为null,右侧主键为null,但辅键不为null,您希望比较什么?两条记录合并的逻辑是什么?是
((primary==primary)还是(alternative==alternative))
?或者,当主键和可选键都存在时,还有其他逻辑吗?现在是的,它的prime=prime,alternate=alternate,Id更喜欢的是如果不是prime=prime,那么alternate=alternate一些问题:如果可以使用简单的filter函数,为什么要使用RichFlatMap?而且,如果你想管理复杂的键,我认为你可以使用KeySelector函数()是的,一个简单的过滤器会更合适,但是这不会影响解决方案-键选择器需要是确定性的,它不会返回你所说的相关标识,如果我重写hashscode和equals方法,那么我就可以通过一个复合对象设置密钥。太棒了,这可能有用。我会试试看。基本上,我只想用相同的键或备用键对状态进行分组。我使用不同类型的传感器,其中一些传感器会返回pk,而另一个传感器只能返回相对id,即备用密钥。上面的逻辑是一个简单的例子,我应该进一步阐述吗?似乎至少值得一试。很容易创建一个单元测试来验证。它有效吗?添加后续操作对可能遇到相同情况的其他人非常有用,谢谢。您好,不幸的是,它不起作用,因为哈希值需要是确定性的,有时其中不会有值,因此哈希值不会相同,也不会是同一个对象,不过谢谢您的建议
DataStream<MyPOJO> primaryKey = stream.flatMap(new RichFlatMapFunction<MyPOJO mypojo, MyPOJO mypojo>() {
@Override
public void flatMap(MyPOJO mypojo, Collector<MyPOJO> collector) throws Exception {
if(mypojo.PrimaryKey() != null){
collector.collect(MyPOJO);
}
}
});
DataStream<MyPOJO> alternateKey = stream.flatMap(new RichFlatMapFunction<MyPOJO mypojo, MyPOJO mypojo>() {
@Override
public void flatMap(MyPOJO mypojo, Collector<MyPOJO> collector) throws Exception {
if(mypojo.getAlternateKey() != null){
collector.collect(mypojo);
}
}
});
DataStream<MyPOJO> both = stream.flatMap(new RichFlatMapFunction<MyPOJO mypojo, MyPOJO mypojo>() {
@Override
public void flatMap(MyPOJO mypojo, Collector<MYPOJO> collector) throws Exception {
if(mypojo.getAlternateKey() != null && mypojo.getPrimaryKey() !=null ){
collector.collect(mypojo);
}
}
});
//Join them
both.join(alternateKey)
.where(MyPOJO::getAlternateKey)
.equalTo(MyPOJO::getAlternateKey)
.window(TumblingEventTimeWindows.of(Time.milliseconds(1)))
.apply (new JoinFunction<MyPOJO, MyPOJO, MyPOJO>(){
@Override
public StateObject join(MyPOJO Mypojo, MyPOJO mypojo2) throws Exception {
// Some Join logic to keep both states
return stateObject2;
}
});
:: repeat for primary key stream ...
// keyby at the end
both.keyBy(MyPOJO::getPrimaryKey)