Android Room:针对字符串列的查询列表项目

发布于 2025-01-22 02:33:59 字数 343 浏览 0 评论 0 原文

我有一个字符串列表:

val mylist = listOf("cat","flower")

还有一个具有字符串键入列的表,名为问题 我可以编写查询,以找到与列表项目之一完全匹配的问题:

@Query("SELECT * FROM objects WHERE question IN (:mylist)")
List<Object> queryObjects(List<String> mylist);

但是实际上,问题列数据不是单词类型,而是字符串。我需要找到列表项中的每个列表中的每个列表。

I have an list of strings:

val mylist = listOf("cat","flower")

and a table that has a string typed column named question
I can write the query to find questions that are exactly matched with one of list items:

@Query("SELECT * FROM objects WHERE question IN (:mylist)")
List<Object> queryObjects(List<String> mylist);

But in fact the question column data is not of single word type, but string. I need to find results that every one of the list items are in that strings .for example the record : is this a cat

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

-黛色若梦 2025-01-29 02:33:59

IN的使用基本上是在in子句左侧的表达式的AN =测试,以右侧的值列表。这仅考虑确切的匹配。

但是,您想要的是多个,例如,带有野生字符,每个之间的都像 eg eg 等问题,例如'%cat当其他问题结束时,或> 或可能是递归的公共表达式(CTE)时,例如'%flower%'等问题。

前两个(喜欢或案例)可能必须通过 @rawquery 在运行时构建的类似/case子句。

递归CTE选项基本上将构建单词列表(但是,如果包括空格(例如标点符号)以外的其他任何内容,可能会变得更加复杂。)

另一种选择是考虑全文搜索(FTS)。您可能希望参考

工作示例 like there emper

there是一个实现最简单的,多个喜欢的条款的示例ORS: -

对象(实体): -

@Entity
data class Objects(
    @PrimaryKey
    val id: Long? = null,
    val question: String
) 

alldao (daos): -

@Dao
interface AllDAO {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(objects: Objects)

    @RawQuery
    fun getObjectsRawQuery(query: SupportSQLiteQuery): List<Objects>

    fun getObjects(values: List<String>): List<Objects> {
        var i = 0
        val sb = StringBuilder().append("SELECT * FROM objects WHERE ")
        for(v in values) {
            if (i++ > 0) {
                sb.append(" OR ")
            }
            sb.append(" question LIKE '%${v}%'")
        }
        sb.append(";")
        return getObjectsRawQuery(SimpleSQLiteQuery(sb.toString()))
    }
}

thedatabase (不使用 .allomainthreadqueries 为方便和简短): -

@Database(entities = [Objects::class], version = 1, exportSchema = false)
abstract class TheDatabase: RoomDatabase() {
    abstract fun getAllDAO(): AllDAO

    companion object {
        var instance: TheDatabase? = null
        fun getInstance(context: Context): TheDatabase {
            if (instance == null) {
                instance = Room.databaseBuilder(context,TheDatabase::class.java,"the_database.db")
                    .allowMainThreadQueries()
                    .build()
            }
            return instance as TheDatabase
        }
    }
}

将其全部放在一起,加载一些测试数据并运行一些提取物: -

class MainActivity : AppCompatActivity() {
    lateinit var db: TheDatabase
    lateinit var dao: AllDAO
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        db = TheDatabase.getInstance(this)
        dao = db.getAllDAO()

        dao.insert(Objects(question = "This is a cat."))
        dao.insert(Objects(question = "This is a flower."))
        dao.insert(Objects(question = "this is nothing."))
        dao.insert(Objects(question = "The quick brown fox jumped over the lazy dog"))

        logObjects(dao.getObjects(listOf("cat","dog")),"Extract1\t")
        logObjects(dao.getObjects(listOf("flower","cat")),"Extract2\t")
        logObjects(dao.getObjects(listOf("brown","nothing")),"Extract3\t")
    }

    fun logObjects(objects: List<Objects>,prefix: String) {
        for (o in objects) {
            Log.d("OBJECTINFO","$prefix Question is ${o.question} ID is ${o.id}")
        }
    }
}

结果

2022-04-18 04:58:05.471 D/OBJECTINFO: Extract1   Question is This is a cat. ID is 1
2022-04-18 04:58:05.471 D/OBJECTINFO: Extract1   Question is The quick brown fox jumped over the lazy dog ID is 4

2022-04-18 04:58:05.473 D/OBJECTINFO: Extract2   Question is This is a cat. ID is 1
2022-04-18 04:58:05.473 D/OBJECTINFO: Extract2   Question is This is a flower. ID is 2

2022-04-18 04:58:05.474 D/OBJECTINFO: Extract3   Question is this is nothing. ID is 3
2022-04-18 04:58:05.474 D/OBJECTINFO: Extract3   Question is The quick brown fox jumped over the lazy dog ID is 4
  • 在上述内容中,没有考虑处理处理空列表(由于的语法错误从对象中选择 *; >)。这是一个例子只是为了证明基本原则。

The use of IN is basically an = test of the expression on the the left of the IN clause against the list of values on the right. That is only exact matches are considered.

However, what you want is multiple LIKE's with wild characters, and an OR between each LIKE e.g question LIKE '%cat%' OR question LIKE '%flower%' or perhaps CASE WHEN THEN ELSE END or perhaps a recursive common table expression (CTE).

The former two (LIKEs or CASEs) would probably have to be done via an @RawQuery where the LIKE/CASE clauses are built at run time.

The Recursive CTE option would basically build a list of words (but could get further complicated if, anything other than spaces, such as punctuation marks were included.)

Another option could be to consider Full Text Search (FTS). You may wish to refer to https://www.raywenderlich.com/14292824-full-text-search-in-room-tutorial-getting-started

Working Example LIKE's

Here's an example of implementing the simplest, multiple LIKEs clauses separated with ORs:-

Objects (the Entity):-

@Entity
data class Objects(
    @PrimaryKey
    val id: Long? = null,
    val question: String
) 

AllDAO (the Daos):-

@Dao
interface AllDAO {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(objects: Objects)

    @RawQuery
    fun getObjectsRawQuery(query: SupportSQLiteQuery): List<Objects>

    fun getObjects(values: List<String>): List<Objects> {
        var i = 0
        val sb = StringBuilder().append("SELECT * FROM objects WHERE ")
        for(v in values) {
            if (i++ > 0) {
                sb.append(" OR ")
            }
            sb.append(" question LIKE '%${v}%'")
        }
        sb.append(";")
        return getObjectsRawQuery(SimpleSQLiteQuery(sb.toString()))
    }
}

TheDatabase (not uses .allowMainThreadQueries for convenience and brevity):-

@Database(entities = [Objects::class], version = 1, exportSchema = false)
abstract class TheDatabase: RoomDatabase() {
    abstract fun getAllDAO(): AllDAO

    companion object {
        var instance: TheDatabase? = null
        fun getInstance(context: Context): TheDatabase {
            if (instance == null) {
                instance = Room.databaseBuilder(context,TheDatabase::class.java,"the_database.db")
                    .allowMainThreadQueries()
                    .build()
            }
            return instance as TheDatabase
        }
    }
}

Putting it all together, loading some test data and running some extracts:-

class MainActivity : AppCompatActivity() {
    lateinit var db: TheDatabase
    lateinit var dao: AllDAO
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        db = TheDatabase.getInstance(this)
        dao = db.getAllDAO()

        dao.insert(Objects(question = "This is a cat."))
        dao.insert(Objects(question = "This is a flower."))
        dao.insert(Objects(question = "this is nothing."))
        dao.insert(Objects(question = "The quick brown fox jumped over the lazy dog"))

        logObjects(dao.getObjects(listOf("cat","dog")),"Extract1\t")
        logObjects(dao.getObjects(listOf("flower","cat")),"Extract2\t")
        logObjects(dao.getObjects(listOf("brown","nothing")),"Extract3\t")
    }

    fun logObjects(objects: List<Objects>,prefix: String) {
        for (o in objects) {
            Log.d("OBJECTINFO","$prefix Question is ${o.question} ID is ${o.id}")
        }
    }
}

Result

2022-04-18 04:58:05.471 D/OBJECTINFO: Extract1   Question is This is a cat. ID is 1
2022-04-18 04:58:05.471 D/OBJECTINFO: Extract1   Question is The quick brown fox jumped over the lazy dog ID is 4

2022-04-18 04:58:05.473 D/OBJECTINFO: Extract2   Question is This is a cat. ID is 1
2022-04-18 04:58:05.473 D/OBJECTINFO: Extract2   Question is This is a flower. ID is 2

2022-04-18 04:58:05.474 D/OBJECTINFO: Extract3   Question is this is nothing. ID is 3
2022-04-18 04:58:05.474 D/OBJECTINFO: Extract3   Question is The quick brown fox jumped over the lazy dog ID is 4
  • Note in the above no consideration has been given to handling an empty list (a failure would occur due to the syntax error of SELECT * FROM objects WHERE ;). That is the example is just intended to demonstrate the basic principle.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文