Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

194
Visualizações
How to add multiple or filter conditions based on incoming parameters using exposed?

I have to add or conditions using the parameter values to the query.

Example: select * from users where email = "abc@xyz.com" or phone="1234123412";

The user might send both fields or only one. I want to do this in a loop for each field and add each one of them in or where condition.

val query = Users.selectAll()
**var predicates = Op.build { Users.id inList listOf<Int>()}**
for((k, v) in params) {
    val value = URLDecoder.decode(v.first(), "UTF-8")
    predicates = when(k) {
        "email" -> predicates.or(Users.email eq value)
        "phone" -> predicates.or(Users.phone eq value)
    }
}
query.andWhere { predicates }

The above DSL produces the below SQL.

SELECT * from users where (((false = true) OR (users.email = "abc@xyz.com")) OR (users.phone = "1234567890"))

See that false = true? That is because, to use .or method, I have to initialize with a condition. The below given snippet is an unncessary line of code added to initialize the predicate.

var predicates = Op.build { Users.id inList listOf<Int>()}

What is the right way to initialize it so that I can seamlessly add multiple or and and predicates to the query?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

First of all, I would advice to optimize your code like:

    val params = mapOf<String, List<String>>()
    val emails = params.filterKeys { it == "email" }.map { URLDecoder.decode(it.value.first(), "UTF-8") }
    val phones = params.filterKeys { it == "phone" }.map { URLDecoder.decode(it.value.first(), "UTF-8") }

    if (emails.isEmpty() && phones.isEmpty()) {
        error("No suitable params were provided")
    } else {
        Users.select {
            Users.email inList emails or (Users.phone inList phones)
        }
    }

UPD: orWhere function is available in Exposed since 0.16.1 version.

If you want to use pattern-matching (when) please define your local orWhere function the same way andWhere works:

fun Query.orWhere(andPart: SqlExpressionBuilder.() -> Op<Boolean>) = adjustWhere {
    val expr = Op.build { andPart() }
    if(this == null) expr
    else this or expr
}

And use it like:

val query = Users.selectAll()
for((k, v) in params) {
    val value = URLDecoder.decode(v.first(), "UTF-8")
    predicates = when(k) {
        "email" -> query.orWhere { Users.email eq value }
        "phone" -> query.orWhere{ Users.phone eq value }
    }
}

over 4 years ago · Santiago Trujillo Relatório

0

A trick would be to initialize predicates to null and define your own or and and on Op<Boolean>?:

// not sure x's type is correct here, the wiki doesn't give exact signatures
// may also need @JvmName to allow overloading
fun Op<Boolean>?.or(x: Op<Boolean>) = if (this != null) this.or(x) else x

...
var predicates: Op<Boolean>? = null
...
predicates = when(k) {
    "email" -> predicates.or(Users.email eq value)
    "phone" -> predicates.or(Users.phone eq value)
}

Whether it's worth the complication, I doubt: as Giacomo's comment mentions, the database will certainly optimize your original false = true out.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda