Join 卡夫卡连接流按键筛选

Join 卡夫卡连接流按键筛选,join,stream,apache-kafka,apache-kafka-streams,Join,Stream,Apache Kafka,Apache Kafka Streams,我用join streams做了一些非常简单的示例,其中两个主题具有简单的键值结构(整数/字符串),它可以完美地工作 请问,我怎样才能做到: SELECT * FROM stream1, stream2 WHERE stream1.key = stream2.key AND (stream1.key > 50 && stream1.key < 100) AND (stream2.key > 50 AND stream2.key < 100) 我的测试示例

我用join streams做了一些非常简单的示例,其中两个主题具有简单的键值结构(整数/字符串),它可以完美地工作

请问,我怎样才能做到:

SELECT * FROM stream1, stream2
WHERE stream1.key = stream2.key AND (stream1.key > 50 && stream1.key < 100) AND (stream2.key > 50 AND stream2.key < 100)
我的测试示例:

public void joinKStreamToKStreamWhereKeyValueIsIntegerString()引发异常{
字符串uniqueKey=新对象(){
}.getClass().GetEnclosuringMethod().getName();
长时间戳=新日期().getTime();
String firstTopic=String.format(“%1$s\u 1\u%2$s”,uniqueKey,时间戳);
String secondTopic=String.format(“%1$s\u 2\u%2$s”,uniqueKey,时间戳);
String outputTopic=String.format(“%1$s_output_uu%2$s”,uniqueKey,时间戳);
String appIdConfig=String.format(“%1$s\u app\u id\u%2$s”,uniqueKey,时间戳);
String groupIdConfig=String.format(“%1$s\u group\u id\u%2$s”,uniqueKey,时间戳);
List ikv1=Arrays.asList(
新键值(1,“Bruce Eckel”),
新键值(2,“Robert Lafore”),
新键值(3,“安德鲁·坦恩鲍姆”)
);
List ikv2=Arrays.asList(
新的KeyValue(3,“现代操作系统”),
新的KeyValue(1,“用Java思考”),
新的KeyValue(3,“计算机体系结构”),
新的键值(4,“Scala编程”)
);
List expectedResults=Arrays.asList(
新键值(3,“Andrew Tanenbaum/现代操作系统”),
新的KeyValue(1,“Bruce Eckel/Thinking in Java”),
新的KeyValue(3,“安德鲁·坦恩鲍姆/计算机架构”)
);
整数分割=1;
整数复制=1;
Properties topicConfig=新属性();
createTopic(firstTopic、分区、复制、topicConfig);
createTopic(第二主题、分区、复制、topicConfig);
createTopic(outputTopic、分区、复制、topicConfig);
final Serde stringSerde=Serdes.String();
最终Serde integerde=Serdes.Integer();
属性流配置=新属性();
streamsConfiguration.put(StreamsConfig.APPLICATION\u ID\u CONFIG,appIdConfig);
streamsConfiguration.put(StreamsConfig.BOOTSTRAP\u SERVERS\u CONFIG,BOOTSTRAP\u SERVERS\u CONFIG);
streamsConfiguration.put(StreamsConfig.ZOOKEEPER\u CONNECT\u CONFIG,ZOOKEEPER\u CONNECT\u CONFIG);
streamsConfiguration.put(StreamsConfig.KEY\u SERDE\u CLASS\u CONFIG,Serdes.Integer().getClass().getName());
streamsConfiguration.put(StreamsConfig.VALUE\u SERDE\u CLASS\u CONFIG,Serdes.String().getClass().getName());
//将记录刷新到状态存储和下游的提交间隔必须小于
//此集成测试的超时(30秒),以确保我们观察到预期的处理结果。
streamsConfiguration.put(StreamsConfig.COMMIT\u INTERVAL\u MS\u CONFIG,10*1000);
streamsConfiguration.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,“最早”);
//使用一个临时目录来存储状态,该目录将在测试后自动删除。
streamsConfiguration.put(StreamsConfig.STATE_DIR_CONFIG,TestUtils.tempDirectory().getAbsolutePath());
KStreamBuilder builder=新的KStreamBuilder();
KStream firstStream=builder.stream(integersde、stringSerde、firstTopic);
KStream secondStream=builder.stream(integersde、stringSerde、secondTopic);
KStream outputStream=firstStream.join(secondStream,(l,r)->{
返回l+“/”+r;
},JoinWindows.of(TimeUnit.SECONDS.toMillis(5)),integersde,stringSerde,stringSerde);
outputStream.to(integerSerde、stringSerde、outputTopic);
KafkaStreams streams=新的KafkaStreams(构建者、流配置);
streams.start();
属性pCfg1=新属性();
pCfg1.put(ProducerConfig.BOOTSTRAP\u SERVERS\u CONFIG,BOOTSTRAP\u SERVERS\u CONFIG);
pCfg1.put(ProducerConfig.ACKS_CONFIG,“all”);
pCfg1.put(ProducerConfig.RETRIES\u CONFIG,0);
pCfg1.put(ProducerConfig.KEY\u SERIALIZER\u CLASS\u CONFIG,IntegerSerializer.CLASS);
pCfg1.put(ProducerConfig.VALUE\u SERIALIZER\u CLASS\u CONFIG,StringSerializer.CLASS);
IntegrationTestUtils.ProduceKeyValues同步(firstTopic、ikv1、pCfg1);
属性pCfg2=新属性();
pCfg2.put(ProducerConfig.BOOTSTRAP\u SERVERS\u CONFIG,BOOTSTRAP\u SERVERS\u CONFIG);
pCfg2.put(ProducerConfig.ACKS_CONFIG,“all”);
pCfg2.put(ProducerConfig.RETRIES\u CONFIG,0);
pCfg2.put(ProducerConfig.KEY\u SERIALIZER\u CLASS\u CONFIG,IntegerSerializer.CLASS);
pCfg2.put(ProducerConfig.VALUE\u SERIALIZER\u CLASS\u CONFIG,StringSerializer.CLASS);
IntegrationTestUtils.ProduceKeyValues同步集成(第二主题,ikv2,pCfg2);
Properties consumerConfig=新属性();
consumerConfig.put(consumerConfig.BOOTSTRAP\u SERVERS\u CONFIG,BOOTSTRAP\u SERVERS\u CONFIG);
consumerConfig.put(consumerConfig.GROUP\u ID\u CONFIG,groupIdConfig);
consumerConfig.put(consumerConfig.AUTO_OFFSET_RESET_CONFIG,“最早”);
consumerConfig.put(consumerConfig.KEY\u反序列化器\u CLASS\u CONFIG,IntegerDeserializer.CLASS);
consumerConfig.put(consumerConfig.VALUE\u反序列化程序\u类\u配置,StringDeserializer.CLASS);
List actualResults=IntegrationTestUtils.waitUntilMinKeyValueRecordsReceived(consumerConfig、outputTopic、expectedResults.size());
streams.close();
资产(实际结果)。包含(预期结果)的实际要素;
}

希望我解释得很好,谢谢你的帮助

您只需在加入之前应用一个
过滤器

outputStream=firstStream.filter(…).join(secondStream.filter(…),…);
如果您想加入
stream1.genericRecordkey.someId
,您需要先提取
someId
,并将其设置为key:

firstStream.selectKey((k,v)->v.someId)).join(secondStream.selectKey((k,v)->v.someId),…);
有关更多详细信息,请查看
SELECT * FROM stream1, stream2
WHERE stream1.genericRecordkey.someId. = stream2.genericRecordkey.someId