使用Spring Data和Reactive MongoDB推送Flux

时间:2018-05-30 14:17:51

标签: mongodb spring-boot kotlin spring-data spring-data-mongodb

我使用的是Spring Boot 2.0.2,我希望使用Spring Data将Flux的内容插入到MongoDB文档中的数组中,使用{{{{{}} { 3}}。例如(Kotlin代码):

val mongo : ReactiveMongoOperations = ...
data class Something(val data: String)
val flux = Flux.just(Something("A"), Something("B"))

mongo.upsert(query(where("_id").isEqualTo("myId")),
                        Update().push("myArray").each(flux),
                        "collection")

(请注意,这只是一个示例,并且在实际代码中未使用flux生成Flux.just(..)

虽然这有效,但它并没有产生我想要的结果:

{ "_id" : "myId", "myArray" : [ { "array" : [ { "data" : "A" }, { "data" : "B" } ], "_class" : "reactor.core.publisher.FluxArray" } ] }

我希望结果如下:

{ "_id" : "myId", "myArray" : [ { "data" : "A" }, { "data" : "B" } ] }

即。 Spring Data序列化了Flux中的内容(元素),而不是Flux本身。此示例产生正确的结果:

mongo.upsert(query(where("_id").isEqualTo("myId")),
                        Update().push("myArray").each(Something("A"), Something("B")),
                        "collection")

如何在不阻止的情况下实现

1 个答案:

答案 0 :(得分:1)

TL; DR

您需要预先收集项目并$push收集项目。

解释

您不能将反应性包装类型用作MongoDB查询的值,因为它们需要预先解析为值。您可以通过应用collectList()flatMap()运算符来实现您的目标:

val flux: Flux<Something>

flux.collectList()
    .flatMap { mongo.upsert(query(where("_id").isEqualTo("myId")),
                    Update().push("myArray").each(it),
                    "collection")  }

如果元素数量超出合理限制,那么buffer(n)可能是更合适的选择。