1

I'm trying to do an conditional find in MongoDB. Given a collection with the following fields:

itemId: Long
itemName: String
unconsumed: Boolean
snooze: Boolean
expiryTs: Long

I want to find all items depending on whether they are unconsumed, depending on snooze the expiryTs should by conditionally evaluated, like this:

if (snooze)
    expiryTs < now + 1
else
    expiryTs < now + 2

I use KMongo to query the collection, but with the following query

collection.find(and(PantryDomain::unconsumed eq true,
                    expr(cond(PantryDomain::snooze eq true,
                              PantryDomain::expiryTs lt Instant.now().plus(1, ChronoUnit.DAYS).toEpochMilli(),
                              PantryDomain::expiryTs lt Instant.now().plus(2, ChronoUnit.DAYS).toEpochMilli()))))

I get this error:

com.mongodb.MongoQueryException: Query failed with error code 16020 and error message 'Expression $lt takes exactly 2 arguments. 1 were passed in.' on server localhost:27017

Any idea what's wrong with the query? Thanks :-)

1 Answers1

0

can you try

collection.find(and(PantryDomain::unconsumed eq true,
                    expr(cond(PantryDomain::snooze eq true,
                              lt PantryDomain::expiryTs Instant.now().plus(1, ChronoUnit.DAYS).toEpochMilli(),
                              lt PantryDomain::expiryTs Instant.now().plus(2, ChronoUnit.DAYS).toEpochMilli()))))

you can also simplify it as

collection.find(and(PantryDomain::unconsumed,
                    expr(cond(PantryDomain::snooze,
                              lt PantryDomain::expiryTs Instant.now().plus(1, ChronoUnit.DAYS).toEpochMilli(),
                              lt PantryDomain::expiryTs Instant.now().plus(2, ChronoUnit.DAYS).toEpochMilli()))))
Saravana
  • 12,647
  • 2
  • 39
  • 57
  • Unfortunately, this won't work, for once `lt` is an infix function `infix fun KProperty.lt(item: T): Bson = Filters.lt(path(), item)` simplifying also won't work, but this is not an issue – christian meyer Jan 22 '19 at 08:56