我有一个 sqlite 数据库,其中有一个名为 kanji 的表,其中有一列名为 english_meaning。我想查询一个“词”。
这是我现有的查询和代码:
public Cursor fetchAllKanjiWithQuery(String input) {
input = "%" + input + "%";
String query = "SELECT * FROM kanji WHERE literal LIKE ? OR radicals LIKE ? OR english_meaning LIKE ? OR kun_reading LIKE ? OR romaji LIKE ? ORDER BY stroke_count";
String[] selectionArgs = new String[]{input, input, input, input, input};
Cursor cursor = db.rawQuery(query, selectionArgs);
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;
}
输入为“one”时,english_meaning 为“bone”或“oneself”的结果将匹配。
但是,我只对带有“one”这个词的字符串感兴趣。例如,有效匹配应包括:
即“一”可以出现在字符串的开头或结尾,与其他字符之间用空格隔开。如果可能,还应允许“一”后跟标点符号,例如“,”和“.”。
目前,我使用 LIKE 和 % input % 的查询没有给出预期的结果。如何解决?
为什么不这样做:
SELECT *
from kanji
where (english_meaning = 'one'
or english_meaning = 'one.'
or english_meaning = 'one,'
or english_meaning like 'one %'
or english_meaning like '% one %'
or english_meaning like '% one'
or english_meaning like '% one.'
or english_meaning like '% one,')
FTS4
或 FTS5
这样的全文搜索引擎的可用性,它是为高效搜索大型datasets
.而设计的
你可以创建一个虚拟表来索引你想要搜索的文本列,然后它使用 SQL 来搜索列中的单词或短语。它将为您处理标记化、词干提取和其他文本处理任务,以手动列出它们。
像这样使用FTS在你的
one
的english_meaining
中搜索单词kanji
:
为
english_meaning
列创建虚拟表:
CREATE VIRTUAL TABLE kanji_fts USING FTS5(english_meaning);
使用
data
表中的 kanji
填充虚拟表:
INSERT INTO kanji_fts(rowid, english_meaning) SELECT rowid, english_meaning FROM kanji;
在表格中搜索单词
one
:
SELECT * FROM kanji WHERE rowid IN (SELECT rowid FROM kanji_fts WHERE english_meaning MATCH 'one');
它将返回
kanji
的所有行,并且 english_meaning
列将包含 one
作为一个单独的词。
FTS
允许您以最少的代码和高性能进行搜索。
这对我有用:
// Create the virtual table if it doesn't exist
db.execSQL("CREATE VIRTUAL TABLE IF NOT EXISTS kanji_fts USING FTS5(english_meaning);");
// Populate the virtual table with data if it's empty
Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM kanji_fts", null);
cursor.moveToFirst();
int count = cursor.getInt(0);
if (count == 0) {
db.execSQL("INSERT INTO kanji_fts(rowid, english_meaning) SELECT rowid, english_meaning FROM kanji;");
}
// Perform a search on the virtual table
String query = "SELECT * FROM kanji WHERE rowid IN (SELECT rowid FROM kanji_fts WHERE english_meaning MATCH ?) ORDER BY stroke_count";
String[] selectionArgs = new String[]{"one"};
cursor = db.rawQuery(query, selectionArgs);
// Process the results
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;