[英]Android room: query list items against string column
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:和一个包含名为
question
的字符串类型列的表 我可以编写查询来查找与列表项之一完全匹配的问题:
@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
我需要找到每个列表项都在该字符串中的结果。例如记录:
is this a cat
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. IN 的使用基本上是对 IN 子句左侧的表达式与右侧值列表的 = 测试。 That is only exact matches are considered.
那只是考虑完全匹配。
However, what you want is multiple LIKE 's with wild characters, and an OR between each LIKE eg question LIKE '%cat%' OR question LIKE '%flower%'
or perhaps CASE WHEN THEN ELSE END
or perhaps a recursive common table expression (CTE).但是,您想要的是多个带有通配符的LIKE ,以及每个LIKE例如问题 LIKE '%cat%' OR
question LIKE '%cat%' OR question LIKE '%flower%'
或CASE WHEN THEN ELSE END
或递归公用表表达式之间的 OR (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.前两个(LIKE 或 CASE)可能必须通过
@RawQuery
完成,其中 LIKE/CASE 子句是在运行时构建的。
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.)递归 CTE 选项基本上会构建一个单词列表(但如果包含除空格以外的任何内容(例如标点符号),可能会变得更加复杂。)
Another option could be to consider Full Text Search (FTS).另一种选择是考虑全文搜索 (FTS)。 You may wish to refer to https://www.raywenderlich.com/14292824-full-text-search-in-room-tutorial-getting-started
不妨参考https://www.raywenderlich.com/14292824-full-text-search-in-room-tutorial-getting-started
Working Example LIKE's工作示例LIKE's
Here's an example of implementing the simplest, multiple LIKEs clauses separated with ORs:-下面是实现最简单的多个 LIKE 子句的示例,这些子句用 OR 分隔:-
Objects (the Entity):-对象(实体):-
@Entity
data class Objects(
@PrimaryKey
val id: Long? = null,
val question: String
)
AllDAO (the Daos):- AllDAO (道):-
@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):- TheDatabase (为了方便和简洁,不使用
.allowMainThreadQueries
):-
@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
SELECT * FROM objects WHERE;
).SELECT * FROM objects WHERE;
的语法错误,会发生失败)。 That is the example is just intended to demonstrate the basic principle.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.