Thommy
Thommy

Reputation: 5407

Realm: Query on condition that a list property contains a specific element

I have a realm database containing a set of article objects. Each of those article objects contains a list of ValidityTimeFrame objects containing two date objects. As the name says, these state in which time intervals the item is valid.

class Article(
    var validDates : List<ValidityTimeFrame>
)

class ValidityTimeFrame(
    var validFrom: Date = Date(),
    var validUntil: Date = Date()
)

I now want to query all articles from the database, where one of those validDates states that the item is valid e.g. today's date is inbetween validFrom and validUntil.

Upvotes: 2

Views: 1644

Answers (1)

EpicPandaForce
EpicPandaForce

Reputation: 81539

You'd expect the following to work, but it would query the following:

Get articles where the valid dates contains at least one where the provided date is greater than or equal to the validFrom, AND there is at least one where the provided date is less than the validTo

Therefore, this doesn't work (for example with date [09.11-09.13] and then [09.17-09.19], it would actually still return the item if you are currently on 09.15)

val date = Calendar.getInstance().getTime()
val articles = realm.where<Article>()
                    .beginGroup()
                    .greaterThanOrEqualTo("validDates.validFrom", date)
                    .lessThan("validDates.validTo", date)
                    .endGroup()
                    .findAll()

However even without subquery support you can actually work around this if you invert the query through a linking objects:

class Article(
    var validDates : RealmList<ValidityTimeFrame>
)

class ValidityTimeFrame(
    var validFrom: Date = Date(),
    var validUntil: Date = Date()

    @LinkingObjects("validDates")
    val articles: RealmResults<Article>? = null

)

Because now you can do

val articles = realm.where<ValidityTimeFrame>()
                    .greaterThanOrEqualTo("validFrom", date)
                    .lessThan("validTo", date)
                    .findAll()
                    .flatMap { it.articles!! }
                    .distinct() // assumes `equals` by primary key of Article

Although you still need to make sure you evaluate this when a RealmResults<Article> over the whole table changes to make sure you stay in sync.

Please verify that I'm not misleading you, though.

Upvotes: 2

Related Questions