Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.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 如何在KStream(Kafka Streams)中连接列表的每个元素_Java_Apache Kafka_Apache Kafka Streams - Fatal编程技术网

Java 如何在KStream(Kafka Streams)中连接列表的每个元素

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

例如,我有一个购物车的KStream,每个购物车都有一个产品id列表。此外,还有一个包含产品的KStream。我如何把它们连接在一起

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

    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连接起来

  • 对中间结果进行分组和聚合

  • 最后加入shoppingCart KStream

    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,也许你可以看看在加入后,我会对汽车店内的产品进行聚合。请看下面的聚合示例: