Spring Boot Kotlin Reactive: как связать результаты нескольких запросов MongoDB вместе для одного ответа?

Я сейчас экспериментирую с Spring-Boot 2 Kotlin Reactive. Одна из моих конечных точек должна иметь возможность разрешать номер телефона из MongoDB человеку, компании или отделу.

В результате отображаемое имя должно, например, для телефона должна быть возвращена в виде строки.

Результат можно изменить с помощью параметров в запросе:

http: // localhost: 8080 / api / v1 / numbers / find / xxxxxxxxxxx? asString = true & firstname = 2 & lastname = 1 & company = 3 & Department = 4

Значения имени, фамилии, компании и отдела указывают порядок в отображаемом имени.

Если «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.
Alejandro Navas 23.04.2018 13:12
1
1
78
0

Другие вопросы по теме