Java 如何在KStream(Kafka Streams)中连接列表的每个元素
例如,我有一个购物车的KStream,每个购物车都有一个产品id列表。此外,还有一个包含产品的KStream。我如何把它们连接在一起Java 如何在KStream(Kafka Streams)中连接列表的每个元素,java,apache-kafka,apache-kafka-streams,Java,Apache Kafka,Apache Kafka Streams,例如,我有一个购物车的KStream,每个购物车都有一个产品id列表。此外,还有一个包含产品的KStream。我如何把它们连接在一起 public class ShoppingCart { List<ProductKey> productKeys; } public class Product { ProductKey key; String name; } public class ProductKey { String id; } KStre
public class ShoppingCart {
List<ProductKey> productKeys;
}
public class Product {
ProductKey key;
String name;
}
public class ProductKey {
String id;
}
KStream<String, ShoppingCart> shoppingCartKStream;
KStream<ProductKey, Product> productKStream;
公共类购物车{
列出产品密钥;
}
公共类产品{
产品密钥;
字符串名;
}
公共类ProductKey{
字符串id;
}
KStream shoppingCartKStream;
KStream productKStream;
我想要的结果是这样的
KStream<String, ShoppingCartWithProducts> joinedStream;
public class ShoppingCartWithProducts {
List<Product> products;
}
KStream-joinedStream;
公共类购物车{
列出产品清单;
}
有没有一种简单的方法来存档
编辑:
我知道有办法,但我觉得太复杂了。简言之:
KStream<String, ProductKey> productKeyStream = shoppingCartKStream
.flatMap((key, shoppingCart) -> shoppingCart.productKeys.stream()
.map(productKey -> KeyValue.pair(key, productKey))
.collect(Collectors.toList())
);
KTable<String, Product> productStreamWithShoppingCartKey = productKeyStream.toTable()
.join(
productKStream.toTable(),
productKey -> productKey,
(productKey, product) -> product
);
KTable<String, ArrayList<Product>> productListStream = productStreamWithShoppingCartKey
.groupBy(KeyValue::pair)
.aggregate(
(Initializer<ArrayList<Product>>) ArrayList::new,
(key, value, aggregate) -> addProductToList(aggregate, value),
(key, value, aggregate) -> removeProductFromList(aggregate, value)
);
KStream<String, ShoppingCartWithProducts> shoppingCartWithProductsKStream = shoppingCartKStream.join(
productListStream,
(shoppingCart, productList) -> new ShoppingCartWithProducts(productList)
);
KStream<String, ProductKey> productKeyStream = shoppingCartKStream
.flatMap((key, shoppingCart) -> shoppingCart.productKeys.stream()
.map(productKey -> KeyValue.pair(key, productKey))
.collect(Collectors.toList())
);
KTable<String, Product> productStreamWithShoppingCartKey = productKeyStream.toTable()
.join(
productKStream.toTable(),
productKey -> productKey,
(productKey, product) -> product
);
KTable<String, ArrayList<Product>> productListStream = productStreamWithShoppingCartKey
.groupBy(KeyValue::pair)
.aggregate(
(Initializer<ArrayList<Product>>) ArrayList::new,
(key, value, aggregate) -> addProductToList(aggregate, value),
(key, value, aggregate) -> removeProductFromList(aggregate, value)
);
KStream<String, ShoppingCartWithProducts> shoppingCartWithProductsKStream = shoppingCartKStream.join(
productListStream,
(shoppingCart, productList) -> new ShoppingCartWithProducts(productList)
);
KStream productKeyStream=shoppingCartKStream
.flatMap((key,shoppingCart)->shoppingCart.productKeys.stream()
.map(productKey->KeyValue.pair(key,productKey))
.collect(收集器.toList())
);
KTable productStreamWithShoppingCartKey=productKeyStream.toTable()
.加入(
productKStream.toTable(),
productKey->productKey,
(productKey,product)->product
);
KTable productListStream=productStreamWithShoppingCartKey
.groupBy(键值::对)
.合计(
(初始值设定项)ArrayList::new,
(键,值,聚合)->addProductToList(聚合,值),
(键,值,聚合)->removeProductFromList(聚合,值)
);
KStream shoppingCartWithProductsKStream=shoppingCartKStream.join(
productListStream,
(shoppingCart,productList)->带有产品的新shoppingCart(productList)
);
当然,它非常简单,我还需要处理墓碑等等。在定义了StreamsBuilder之后,它是Streams DSL的入口点
StreamsBuilder builder = new StreamsBuilder();
您可以使用JoinWindows.of(Duration.ofMinutes(5))
连接5分钟窗口。您必须使用相同类型的两个流的密钥,否则kafka流
无法比较不同类型的密钥。它就像一个数据库连接。因此,我使用String
来表示ShoppingCart
和Product
。然后,.join(…
操作符匹配相同密钥的事件,您可以构建新的事件ShoppingCartWithProducts
KStream<String, ShoppingCart> shoppingCartKStream = ...;
KStream<String, Product> productKStream = ...;
shoppingCartKStream.join(productKStream,
(shop, prod) -> {
log.info("ShoppingCart: {} with Product: {}", shop, prod);
ShoppingCartWithProducts shoppingCartWithProducts = new ShoppingCartWithProducts();
shoppingCartWithProducts.setShoppingCart(shop);
shoppingCartWithProducts.setProduct(prod);
return shoppingCartWithProducts;
},
JoinWindows.of(Duration.ofMinutes(5)),
StreamJoined.with(Serdes.String(),
new JsonSerde<>(ShoppingCart.class),
new JsonSerde<>(Product.class)))
.foreach((k, v) -> log.info("ShoppingCartWithProducts ID: {}, value: {}", k, v));
KStream shoppingCartKStream=。。。;
KStream productKStream=。。。;
shoppingCartKStream.join(productKStream,
(商店、产品)->{
log.info(“ShoppingCart:{}和产品:{}”,shop,prod);
ShoppingCartWithProducts ShoppingCartWithProducts=新的ShoppingCartWithProducts();
带产品的购物车。设置购物车(商店);
购物车带产品。设置产品(产品);
退货购物车与产品;
},
联合窗口(持续时间为5分钟),
StreamJoined.with(Serdes.String(),
新的JsonSerde(ShoppingCart.class),
新的JsonSerde(Product.class)))
.foreach((k,v)->log.info(“ShoppingCartWithProducts ID:{},value:{},k,v));
你可以找到更详细的信息。Hi@Felipe,谢谢你的回答。也许我遗漏了一些东西,但在你的解决方案中,ShoppingCartWithProducts不再有产品列表,而是只有一个产品?我用简化的解决方案编辑了我的问题,但我发现它太复杂了。如果你想要lis,也许你可以看看在加入后,我会对汽车店内的产品进行聚合。请看下面的聚合示例: