英文:
Spring Webflux - How to aggregate three Flux objects into 1 using Tuple3
问题
我正在尝试使用Tuple3
将3个Flux
对象聚合成一个,但我仍然卡住了。我在网上搜索到可以使用Mono.zip()
,但这不适用于Flux
。
public class OrderService {
private final AppWebClient appWebClient;
public Mono<OrderDetailsAggregate> getAggregatedOrderDetails(List<String> orderNoList1,
List<String> orderNoList2, List<String> orderNoList3) {
Flux<Map<String, List<String>>> fluxOne = this.appWebClient.getFluxOne(orderNoList1);
Flux<Map<String, String>> fluxTwo = this.appWebClient.getFluxTwo(orderNoList2);
Flux<Map<String, List<String>>> fluxThree = this.appWebClient.getFluxThree(orderNoList3);
return Mono.zip(fluxOne, fluxTwo, fluxThree).map(this::combine); //error here
}
private OrderDetailsAggregate combine(
Tuple3<Flux<Map<String, List<String>>>, Flux<Map<String, String>>, Flux<Map<String, List<String>>> > tuple) {
return OrderDetailsAggregate.create(tuple.getT1(), tuple.getT2(), tuple.getT3());
}
}
fluxOne
,fluxTwo
,fluxThree
有不同的数据类型。
OrderDetailsAggregate 类
@Data
@ToString
@AllArgsConstructor(staticName = "create")
public class OrderDetailsAggregate {
private Flux<Map<String, List<String>>> fluxOne;
private Flux<Map<String, String>> fluxTwo;
private Flux<Map<String, List<String>>> fluxThree;
}
如何将它们组合起来?
谢谢。
英文:
I am trying to aggregate 3 Flux
objects into 1 using Tuple3
However, I am still stuck. I searched online and saw that you can use Mono.zip()
but that doesn't apply to Flux
.
public class OrderService {
private final AppWebClient appWebClient;
public Mono<OrderDetailsAggregate> getAggregatedOrderDetails(List<String> orderNoList1,
List<String> orderNoList2, List<String> orderNoList3) {
Flux<Map<String, List<String>>> fluxOne = this.appWebClient.getFluxOne(orderNoList1);
Flux<Map<String, String>> fluxTwo = this.appWebClient.getFluxTwo(orderNoList2);
Flux<Map<String, List<String>>> fluxThree = this.appWebClient.getFluxThree(orderNoList3);
return Mono.zip(fluxOne, fluxTwo, fluxThree).map(this::combine); //error here
}
private OrderDetailsAggregate combine(
Tuple3< Flux<Map<String, List<String>>>, Flux<Map<String, String>>, Flux<Map<String, List<String>>> > tuple) {
return OrderDetailsAggregate.create(tuple.getT1(), tuple.getT2(), tuple.getT3());
}
}
fluxOne
, fluxTwo
, fluxThree
have different data types.
OrderDetailsAggregate class
@Data
@ToString
@AllArgsConstructor(staticName = "create")
public class OrderDetailsAggregate {
private Flux<Map<String, List<String>>> fluxOne;
private Flux<Map<String, String>> fluxTwo;
private Flux<Map<String, List<String>>> fluxThree;
}
How do I combine them?
Thank you.
答案1
得分: 1
如果您需要从getAggregatedOrderDetails
方法返回Mono<OrderDetailsAggregate>
,那么为什么不只是创建Mono
对象而不使用zip
:
public Mono<OrderDetailsAggregate> getAggregatedOrderDetails(List<String> orderNoList1,
List<String> orderNoList2, List<String> orderNoList3) {
Flux<Map<String, List<String>>> fluxOne = this.appWebClient.getFluxOne(orderNoList1);
Flux<Map<String, String>> fluxTwo = this.appWebClient.getFluxTwo(orderNoList2);
Flux<Map<String, List<String>>> fluxThree = this.appWebClient.getFluxThree(orderNoList3);
OrderDetailsAggregate aggregate = OrderDetailsAggregate.create(fluxOne, fluxTwo, fluxThree);
return Mono.just(aggregate);
}
英文:
If you need to return Mono<OrderDetailsAggregate>
from getAggregatedOrderDetails
method, then why not just create Mono
object without zip:
public Mono<OrderDetailsAggregate> getAggregatedOrderDetails(List<String> orderNoList1,
List<String> orderNoList2, List<String> orderNoList3) {
Flux<Map<String, List<String>>> fluxOne = this.appWebClient.getFluxOne(orderNoList1);
Flux<Map<String, String>> fluxTwo = this.appWebClient.getFluxTwo(orderNoList2);
Flux<Map<String, List<String>>> fluxThree = this.appWebClient.getFluxThree(orderNoList3);
OrderDetailsAggregate aggregate = OrderDetailsAggregate.create(fluxOne, fluxTwo, fluxThree);
return Mono.just(aggregate);
}
答案2
得分: 1
对我来看,你似乎是将appWebClient
返回的Flux视为Mono的方式来处理。
我猜你想要在OrderDetailsAggregate
中获取所有Flux的值。如果是这样的话,我建议将Flux收集到Mono中,使用Mono.zip
获得一个元组,然后将其映射到你的OrderDetailsAggregate
:
public Mono<OrderDetailsAggregate> getAggregatedOrderDetails(List<String> orderNoList1,
List<String> orderNoList2, List<String> orderNoList3) {
Mono<Map<String, List<String>>> monoOne = this.appWebClient.getFluxOne(orderNoList1).collect(HashMap::new, Map::putAll);
Mono<Map<String, String>> monoTwo = this.appWebClient.getFluxTwo(orderNoList2).collect(HashMap::new, Map::putAll);
Mono<Map<String, List<String>>> monoThree = this.appWebClient.getFluxThree(orderNoList3).collect(HashMap::new, Map::putAll);
return Mono.zip(monoOne, monoTwo, monoThree).map(tuple -> OrderDetailsAggregate.create(tuple.getT1(), tuple.getT2(), tuple.getT3()));
}
如果你只关心Flux中的一个值,那么你可以用next()
替代collect()
。
编辑:我看到你正在向create()
方法传递Flux
。所以这个答案只适用于如果你也更改了那个方法。如果你的OrderDetailsAggregate
是一个DTO而不是一个服务,那么也许最好不要在其中包含Flux逻辑,而是在getAggregatedOrderDetails
方法中执行。
英文:
To me it looks like you are treating the Flux'es your appWebClient
is returning as if they were Mono's.
I assume, you want to have all values of the fluxes in your OrderDetailsAggregate
. Should that be the case, I would suggest to collect
the Flux into a Mono, do a Mono.zip
to get a tuple and map that to your OrderDetailsAggregate
:
public Mono<OrderDetailsAggregate> getAggregatedOrderDetails(List<String> orderNoList1,
List<String> orderNoList2, List<String> orderNoList3) {
Mono<Map<String, List<String>>> monoOne = this.appWebClient.getFluxOne(orderNoList1).collect(HashMap::new, Map::putAll);
Mono<Map<String, String>> monoTwo = this.appWebClient.getFluxTwo(orderNoList2).collect(HashMap::new, Map::putAll);
Mono<Map<String, List<String>>> monoThree = this.appWebClient.getFluxThree(orderNoList3).collect(HashMap::new, Map::putAll);
return Mono.zip(monoOne, monoTwo, monoThree).map(tuple -> OrderDetailsAggregate.create(tuple.getT1(), tuple.getT2(), tuple.getT3()));
}
Should you just care about one value from the flux, then you can replace the collect()
with next()
.
Edit: I see you are passing Flux
to your create()
method. So this answer only applies if you would change that as well. If your OrderDetailsAggregate
is a Dto and not a service, then it would perhaps be a good idea to not have that flux logic in there but rather do it in the getAggregatedOrderDetails
method.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论