gpt4 book ai didi

spring-boot - 在Spring Reactive Programming中如何从两个Flux(Object)获取Flux或List?

转载 作者:行者123 更新时间:2023-12-04 02:04:21 24 4
gpt4 key购买 nike

我是Spring Reactive Project的新手。在我的Spring Boot Controller类中

Flux<House> ( list of all houses in the database) and Flux<Image>



来自服务层,其中给定的 Flux<Image>是给定房屋的图像,例如房屋列表,每个房屋都有自己的图像集合。这意味着我必须遍历 Flux<House>以获得房屋的ID,然后在Image上调用findByHouseId以获得 Flux<Image>,每个Image都具有houseId属性。每个图像对象都具有字符串值"is"或“否”的属性“cover”,以及具有诸如“bedroom”之类的各种字符串值的另一个属性“type”。我想收集一个
list of Flux<Image> like List<Flux<Image>> or List<List<Image>>

仅包含“封面” =="is"或“类型” ==“卧室”的那些图像。如何实现呢?编程代码将回答这个问题。

尝试将以下方法作为解决方案的一部分,但即使是部分解决方案也无法使用:
List<Flux<Image>> imagesList= new ArrayList<Flux<Image>>();
Flux<House> houses = houseService.findAllHouses();

houses.map(house -> house.getId()).subscribe(id -> imageService.findByHouseId(id))
.map(imageFlux ->imagesList.add(imageFlux));

请注意,除非这是唯一的方法,否则我正在寻找不涉及调用block()的解决方案(否定了被动响应的优势)。

在非 react 情况下,这就是我想要的:
List<House> houses  --> List of all houses
Map<String,List<Image>> mapOfImages --> where key is houseId

因此,对于每个房屋,我都可以在 View 模板中遍历房屋时轻松获取该房屋的图像。

这些(房屋和mapOfImages)将传递给模型,例如
model.addAttribute("houses",houses);
model.addAttribute("mapOfImages",mapOfImages);

现在,在thyemleaf View 模板中,我可以:
<div data-th-each="house : ${houses}">
<h3 data-th-text="${house.title}"></h3>
<div data-th-each="image : ${mapOfImages.get(house.houseId)}">
<h5 data-th-text="${image.fileName}"></h5>
<h5 data-th-text="${image.type}"></h5>
</div>
</div>

正在使用的数据库是Mongodb,它具有两个独立的集合:房屋和图像,即没有嵌入式集合,并且将图像与房屋联系起来的唯一东西是图像上的houseId属性。

最佳答案

您基本上想将House对象流转换为Image对象流。

因此,请使用flatMap(),它将Flux<Flux<T>>(或Flux<Mono<T>>)转换为Flux<T>

Mono<List<Image>> images = houseService.findAllHouses() // returns Flux<House>
.flatMap(house -> imageService.findByHouseId(id) // returns Flux<Image>
.filter(image -> "yes".equals(image.getCover()) && ... ))
.collectList(); //returns Mono<List<Image>>

在这里使用 collectList()是可以的,因为您很可能仍希望将 images转换为单个 Mono<ServerResponse>对象:
return images.map(imageList -> ServerResponse.ok()
.body(fromObject(imageList)));

另外,我建议阅读有关 Project Reactor referencewhen to use which operator

编辑:

因此,您需要一个 Mono<Map<String, Collection<Image>>。我的答案将取决于 Image类是否具有对 House的引用。否则,仍然可以,但是答案会更加冗长。

我将描述一种很难的方法,其中 Image不包含 House id。我们需要……,它链接属于特定房屋的图像列表。您可以为此目的定义一个类,也可以只使用 reactor.util.function.Tuple2。有了它,我们可以只使用 collectMap():
Mono<Map<String, Collection<Image>>> images = houseService.findAllHouses()
.flatMap(house -> imageService.findByHouseId(id)
.filter(...)
.map(image -> Tuples.of(id, image)))
.collectMultiMap(tuple -> tuple.getT1(),
tuple -> tuple.getT2());

当然,如果您有对 House的引用,则可以再次省略 map()并直接使用 collectMultiMap:
...
.collectMultiMap(image -> image.getHouseId(), image -> image);

关于spring-boot - 在Spring Reactive Programming中如何从两个Flux(Object)获取Flux或List?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49676422/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com