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>
を取得する必要があります。各画像にはhouseIdプロパティがあります。各画像オブジェクトには、文字列値「yes」または「no」のプロパティ「cover」と、「bedroom」などのさまざまな文字列値を持つ別のプロパティ「type」があります。集めたい
list of Flux<Image> like List<Flux<Image>> or List<List<Image>>
"カバー" == "はい" OR "タイプ" == "ベッドルーム"の画像のみを含む。これを達成する方法?プログラミングコードはこの質問に答えます。
以下はソリューションの一部として試みられましたが、この部分的なソリューションでさえ機能しません:
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()の呼び出し(リアクティブであるという利点を無効にする)を含まないソリューションを探していることに注意してください。
非反応的な状況では、これは私が欲しいものです:
List<House> houses --> List of all houses
Map<String,List<Image>> mapOfImages --> where key is houseId
各家ごとに、ビューテンプレートで家を繰り返し処理しながら、その家の画像を簡単に取得できます。
これら(housesとmapOfImages)は次のようなモデルに渡されます
model.addAttribute("houses",houses);
model.addAttribute("mapOfImages",mapOfImages);
Thyemleafビューテンプレート内で、次のことができます。
<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であり、houseとimageという2つの独立したコレクションがあります。つまり、埋め込まれたコレクションはなく、画像をhouseに結び付けるのは画像のhouseIdプロパティだけです。
基本的に、House
オブジェクトのストリームをImage
オブジェクトのストリームに変換します。
したがって、_Flux<Flux<T>>
_(または_Flux<Mono<T>>
_)を_Flux<T>
_に変換するflatMap()
を使用します。
_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>>
_
とにかくimages
を単一の_Mono<ServerResponse>
_オブジェクトに変換したいので、ここでcollectList()
を使用しても問題ありません。
_return images.map(imageList -> ServerResponse.ok()
.body(fromObject(imageList)));
_
また、 Project Reactorリファレンス について どの演算子をいつ使用するか を読むことをお勧めします。
編集:
したがって、代わりに_Mono<Map<String, Collection<Image>>
_が必要です。私の答えは、Image
クラスがHouse
への参照を持っているかどうかによって異なります。そうでない場合でも問題ありませんが、答えはもっと冗長になります。
Image
にHouse
IDが含まれていない難しい方法を説明します。特定の家に属する画像のリストをリンクするsth。が必要です。この目的でクラスを定義するか、または単に_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);
_