多个有效条件领域查询

时间:2018-06-07 11:42:34

标签: android kotlin realm

说我有3种选择。

狗类有3种

  • 斗牛犬
  • 贵宾犬
  • 帕格

基于3选择,我想我有9个组合?(不确定)。您是否必须使用批量if语句对结果进行排序和查询?在示例中我想显示斗牛犬和贵宾犬?或如果未选择任何内容,我必须显示已注册狗的所有列表。如果我有10个选项,每个选择具有不同的组合,该怎么办?你是否对所有这些使用if语句?这就像100种可能的组合。有没有其他方法可以用其他可能的组合查询领域?那里有很多种狗。如果语句很难做到并且尝试对所有可能的组合进行硬编码

情景:

我有一个狗课

class Dog : RealmObject(){
 var name:String
 var kind:String

}

现在在我的回收者视图中,我有一个由人输入的狗列表。在那人们可以浏览狗。他们可以查询什么类型。 假设他们希望回收者视图显示贵宾犬和哈巴狗哈士奇和贵宾犬。他们只需检查菜单项复选框,然后显示哈士奇和狮子狗的结果

编辑:

我尝试使用以及逻辑运算符。但我无法弄清楚如何进行可能的组合。由于我有5个选择选项和25个可能的组合

,所以我得到的是if语句很多

编辑:  这是我的确切问题。关于领域的多种可能的组合查询。

我的目标是通过依赖领域查询来最小化if语句的编码(如果可能的话)

如果我对组合进行硬编码,它将看起来像这样

if(pug && husky){
 val result = realm.where(Dog::class.java).equalto("kind","husky").equalto("kind",pug").findall()
}
.
.
.
.
. a lot of ifs

1 个答案:

答案 0 :(得分:3)

1。)如果您想支持从数据库中的数据构建查询选项的多字段查询,您可以使用distinct()并创建Set<String>

val kinds = realm.where<Dog>().distinct("kind").findAll().map { it.kind }.toSet()

2。)设置完成后,您可以根据集合中的内容构建查询。

fun filter(realm: Realm, kinds: Set<String>): RealmResults<Dog> { // might wanna introduce a class for the sets
    val query = realm.where<Dog>()
    if(kinds.isNotEmpty()) {
        query.beginGroup()
        kinds.forEachIndexed { index, kind -> 
            if(index != 0) {
                query.or()
            }
            query.equalTo("kind", kind)
        }
        query.endGroup()
    }
    return query.findAll()
}

如果您想发送排序键,那就是.sort(sortKey)

然后如您所见,您可以概括此功能:

fun filter(realm: Realm, vararg filters: Pair<String, Set<*>>): RealmResults<Dog> { 
    val query = realm.where<Dog>()

    fun applyFilters(query: RealmQuery<Dog>, filterParams: Pair<String, Set<*>>) {
        val (fieldName, filter) = filterParams
        if(filter.isNotEmpty()) {
            query.beginGroup()
            filter.forEachIndexed { index, value -> 
                if(index != 0) {
                    query.or()
                }
                query.equalTo(fieldName, value)
            }
            query.endGroup()
        }
    }

    filters.forEachIndexed { index, filter ->
        if(index != 0) {
            query.or()
        }
        applyFilters(query, filter)
    }

    return query.findAll()
}

可以将其称为

val results = filter(realm, 
                "kind" to setOf("Bulldog", "Poodle"), 
                "name" to setOf("George"))

但是请注意,我刚才一时兴起写这个,所以我可能搞砸了某个地方。我不确定您是否可以使用Set<*>,但Set<String>在您的用例中应该可以正常使用。