提问人:SteVio 提问时间:4/23/2018 更新时间:4/23/2018 访问量:99
Spring Boot Kotlin Reactive:如何将多个 MongoDB 查询的结果链接在一起以获得单个响应?
Spring Boot Kotlin Reactive: How do I link the results from multiple MongoDB queries together for a single response?
问:
我现在正在尝试使用 Spring-Boot 2 Kotlin Reactive。我的一个端点应该能够将电话号码从 MongoDB 解析为个人、公司或部门。
因此,例如,对于手机,显示名称应以字符串形式返回。
可以使用请求中的参数更改结果:
firstname、lastname、company 和 department 的值指定显示名称中的顺序。
如果“xxxxxxxxxxx”是一个人的号码,则响应应如下所示:
“姓氏、名字、公司、部门”
我已经找到了解决这个问题的方法,但我想知道是否有更好的方法。
fun findNumberOwner(serverRequest: ServerRequest) =
numberRepository.findByNumber(serverRequest.pathVariable("number")).flatMap { n ->
serverRequest.queryParam("asString")
.filter {
it.trim()
.isNotEmpty().and(it.toBoolean())
}
.map { searchNumberWithStringResult(n, serverRequest.queryParam("firstname"), serverRequest.queryParam("lastname"), serverRequest.queryParam("company"), serverRequest.queryParam("department")) }
.orElse(searchNumberWithJsonResult(n))
}.switchIfEmpty(ServerResponse.notFound().build())
private fun searchNumberWithStringResult(number: Number, firstname: Optional<String>, lastname: Optional<String>, company: Optional<String>, department: Optional<String>): Mono<ServerResponse> {
val ownerId = number.numberOwner
if (ownerId.startsWith("CO-")) {
return ok().body(companyRepository.findById(ownerId).map { it.name })
} else if (ownerId.startsWith("DE-")) {
return ok().body(departmentRepository.findById(ownerId)
.map { dep ->
companyRepository.findById(dep.company)
.map {
it.name
}.zipWith(dep.toMono())
}.flatMap { it ->
it
}.map {
it.t1 + ", " + it.t2.name
})
} else {
val templateMap = mapOf(
Pair("firstname", firstname.orElse("2").toInt()),
Pair("lastname", lastname.orElse("1").toInt()),
Pair("company", company.orElse("0").toInt()),
Pair("department", department.orElse("0").toInt())
)
return ok().body(personRepository.findById(ownerId)
.map { person ->
companyRepository.findById(person.company)
.map {
it.name
}
.switchIfEmpty(Mono.just(""))
.zipWith(person.toMono())
}.flatMap { it ->
it
}.map { t ->
departmentRepository.findById(t.t2.department).map {
mapOf(
Pair(templateMap["firstname"], t.t2.firstName) as Pair<Int, String>,
Pair(templateMap["lastname"], t.t2.lastName) as Pair<Int, String>,
Pair(templateMap["company"], t.t1) as Pair<Int, String>,
Pair(templateMap["department"], it.name) as Pair<Int, String>)
.filter { it.key > 0 }.filter { !it.value.equals("") }.toSortedMap()
}
.switchIfEmpty(Mono.just(
mapOf(
Pair(templateMap["firstname"], t.t2.firstName) as Pair<Int, String>,
Pair(templateMap["lastname"], t.t2.lastName) as Pair<Int, String>,
Pair(templateMap["company"], t.t1) as Pair<Int, String>)
.filter { it.key > 0 }.filter { !it.value.equals("") }.toSortedMap()
))
}.flatMap { it -> it }
.map { it }
.map { myMap ->
var finalDisplayString = ""
myMap.forEach {
finalDisplayString += buildDisplayString(it.key, myMap.size, it.value)
}
finalDisplayString
})
}
}
private fun buildDisplayString(index: Int, maxSize: Int, value: String?): String {
if (value == null) return ""
if (index == 0) {
return "$value, "
} else if (index == maxSize) {
return "$value"
} else {
return "$value, "
}
}
答: 暂无答案
评论
map{it}
什么都不做。与其后跟一个,不如做一个map
flatMap{it->it}
flatMap