在 Kotlin 中使用 Realm 数据库的 BEGINSWITH 过滤查询

问题描述 投票:0回答:1

我在包含 BEGINSWITH (或 CONTAINS )的查询中遇到问题。我正在尝试遵循 Mongo Db 文档中的示例:

用于查找 模型实例的查询未按应有的方式进行过滤。

(所有这些都在 viewModel 中)

这是查询:

val searchResults = realm
        .query<Pantry>("itemName BEGINSWITH $0", searchText.value)
        .find()
        .asFlow()
        .map { results ->
            results.list.toList()
        }
        .stateIn(
            viewModelScope,
            SharingStarted.WhileSubscribed(),
            emptyList()
        )

searchText
是一个字符串,其中包含用户输入的搜索模式,用于查找 Pantry 模型的实例。这是通过使用 TextField 完成的。

'realm' 定义如下: private val Realm =

MyApp.realm
.

我的应用程序是:

class MyApp: Application() {

    companion object {
        lateinit var realm: Realm
    }

    override fun onCreate() {
        super.onCreate()
        realm = Realm.open(
            configuration = RealmConfiguration.create(
                schema = setOf(
                    Pantry::class,
                    Department::class,
                    Market::class,
                )
            )
        )
    }
}

我实现了这个函数来看看发生了什么;查询是否执行任何操作:

suspend fun checkSearchResults(){
        searchResults.collect { results ->
            if (results.isEmpty()) {
                Log.d("Search", "No search results found")
            } else {
                // Loop through or access items in results
                for (item in results) {
                    Log.d("Search", "Found item: ${item.itemName}")
                }
            }
        }

    }

这是用户输入字符时的日志:

The value of searchText: h
D  Found item: bananas
D  Found item: clorox
D  Found item: garbanzos
D  Found item: ham
D  Found item: laundry detergent, pods
D  Found item: milk
D  Found item: olives
D  Found item: pastries
D  Found item: salmon
D  Found item: water, sparkling
D  The value of searchText: ha
D  Found item: bananas
D  Found item: clorox
D  Found item: garbanzos
D  Found item: ham
D  Found item: laundry detergent, pods
D  Found item: milk
D  Found item: olives
D  Found item: pastries
D  Found item: salmon
D  Found item: water, sparkling
D  The value of searchText: ham
D  Found item: bananas
D  Found item: clorox
D  Found item: garbanzos
D  Found item: ham
D  Found item: laundry detergent, pods
D  Found item: milk
D  Found item: olives
D  Found item: pastries
D  Found item: salmon
D  Found item: water, sparkling

这是整个数据库。

因此,从日志中可以明显看出,查询忽略了过滤器并且包含了所有实例。

谁能指出我的失败之处?我想我非常密切地关注文档。

更新: 如果我使用这样的查询:

.query<Pantry>("itemName = $0", searchText.value)
并使用已知的
itemName
,结果是一个空列表。

更新2:

searchResults
不更新。我的理解是,因为它是一个
StateFlow
,所以每次条件发生变化时它都会更新 (
searchtext.value
),但它不会发生。

kotlin android-jetpack-compose realm
1个回答
0
投票

这就是问题所在:

searchResults
的值不是更新,因此即使
textField
searchText variable
发送字符,什么也没有发生。

解决方案:强制更新变量

searchResults

。这是通过将 
searchResults
 的代码封装在函数中并从 
onValueChange
 中的 
textField
 调用该函数来完成的。

并发症:我的理解是,仅仅因为调用了一个函数,并不一定会在

StateFlow

 实体上生成更新,因此通过将其包含在 
.collect 中可以实现这一点。 viewModel
Composable
 之间的复杂性以及在 
variables 声明中使用 varval

因此,为了解决上述并发症,我声明如下:

private val _searchResults = MutableStateFlow<List<Pantry>>(emptyList()) var searchResults: StateFlow<List<Pantry>> = _searchResults.asStateFlow()
1 用于 viewModel,另一个用于 Composable。

这就是函数:

suspend fun fetchSearchResults(searchTerm: String) { realm.query<Pantry>("itemName CONTAINS $0", searchTerm) .find() .asFlow() .map { results -> results.list.toList() } .collect { filteredList -> _searchResults.value = filteredList } }
由于“.collect”,它需要位于 

suspend function

 中。

因此该函数是从

textField

:
调用的

TextField( value = searchText, onValueChange = { viewModel.changeText(it) scope.launch { viewModel.fetchSearchResults(it) } },
效果非常好。测试了它

CONTAINSBEGINSWITH,两者都有效。

© www.soinside.com 2019 - 2024. All rights reserved.