SQLite 匹配单词

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

我有一个 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 % 的查询没有给出预期的结果。如何解决?

java android sql database sqlite
2个回答
1
投票

为什么不这样做:

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,')

0
投票

最好的解决方案是使用像 SQLite

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;
© www.soinside.com 2019 - 2024. All rights reserved.