Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Apache-Flink如何进行映射&;将备用密钥与主键匹配到一个密钥流_Java_Apache Flink_Flink Streaming - Fatal编程技术网

Java Apache-Flink如何进行映射&;将备用密钥与主键匹配到一个密钥流

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

我想要一个更简单、更好、更优雅的方法来解决下面的问题。我还没有看到关于这个主题的任何文档,我确信我目前的方法有一些瓶颈,谢谢

我有一个将Json映射到POJO的流

DataStream<MYPOJO> stream = env.
             addSource( <<kafkaSource>>).map(new EventToPOJO());
DataStream-stream=env。
addSource().map(新的EventToPOJO());
POJO的一些字段将有一个填充的主键,一些字段将有一个填充的备用键,一些字段将同时具有这两个键。我在Flink文档中找到的唯一一个使用两个键的示例是,对复合键使用一个键选择器,但对备用键不使用任何选项

我目前的做法如下:

  • 使用RichFlatMap函数将主键的所有元素收集到流中,Astream
  • 使用RichFlatMap函数将备用密钥的所有元素收集到流中,b流
  • 对同时具有主键和备用键的项目使用richFlatMap,CStream
  • 使用主键上的Cstream连接Astream
  • 将B流与备用键上的Cstream连接起来
  • 最后,按主键输入
  • 
    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)