Sqlite Android 如何实现分词?
How to achieve word boundary in Sqlite Android?
我想实现以下(全文搜索),
SELECT * FROM tablename where columnname REGEXP '[[:<:]]some string[[:>:]]'
我只对全文列中的确切字符串(不仅仅是单词)感兴趣。
我一直在 MySQL 中使用上面的 SQL,现在将大部分代码迁移到 android 应用程序。
但我一直在查看各种帖子,其中提到 Android Sqlite 不支持 REGEXP(例如:link1, link2, link3)。
有没有办法在 Android 中启用 REGEXP?
如果没有,上面的SQL有没有其他选择?
谢谢,
编辑:
目前我在 Android,
中使用 REGEXP 时收到以下异常
android.database.sqlite.SQLiteException: no such function: REGEXP (code 1):...
我知道我们可以使用 GLOB 和 LIKE(或者甚至可以是 MATCH)。 columnname REGEXP '[[:<:]]somestring[[:>:]]'
如何转换为利用GLOB
and/or LIKE
and/or MATCH
?
解决方案 1:
在 的帮助下,以下是我正在使用的(经过一些修改后)
SELECT * FROM tablename where
(columnname GLOB '*some string*' OR columnname GLOB '*Some string*') AND
(
(
(columnname GLOB '*[^a-zA-Z0-9_]some string[^a-zA-Z0-9_]*' AND
columnname GLOB '*some string[^a-zA-Z0-9_]*' AND
columnname GLOB '*[^a-zA-Z0-9_]some string*')
OR
(columnname GLOB '*[^a-zA-Z0-9_]Some string[^a-zA-Z0-9_]*' AND
columnname GLOB '*Some string[^a-zA-Z0-9_]*' AND
columnname GLOB '*[^a-zA-Z0-9_]Some string*')
)
)
GLOB
区分大小写所以我有一个额外的 OR
的第二个解决方案在我的情况下要快得多。
解决方案 2:处理大小写不敏感
SELECT * FROM tablename where
(columnname GLOB '*[sS][oO][mM][eE] [sS][tT][rR][iI][nN][gG]*') AND
(
(
columnname GLOB '*[^a-zA-Z0-9_][sS][oO][mM][eE] [sS][tT][rR][iI][nN][gG][^a-zA-Z0-9_]*' AND
columnname GLOB '*[sS][oO][mM][eE] [sS][tT][rR][iI][nN][gG][^a-zA-Z0-9_]*' AND
columnname GLOB '*[^a-zA-Z0-9_][sS][oO][mM][eE] [sS][tT][rR][iI][nN][gG]*')
)
要实际支持 REGEXP
,您必须添加自己的 regexp() user function。
This link 可能会帮助您了解如何为 Android 创建用户定义的函数——但这并不简单。
如果您的模式非常简单,GLOB operator 可能就足够了。
例如,要执行与此 MYSQL 查询等效的搜索:
SELECT * FROM tablename where columnname REGEXP '[[:<:]]some string[[:>:]]'
你可以在 SQLite 中试试这个:
SELECT * FROM tablename where
columnname GLOB '[^a-zA-Z0-9_]some string[^a-zA-Z0-9_]' OR
columnname GLOB 'some string[^a-zA-Z0-9_]' OR
columnname GLOB '[^a-zA-Z0-9_]some string' OR
columnname GLOB 'some string';
上面的查询使用了这样一个事实,即在 MYSQL 中,单词字符被定义为字母数字字符或下划线。还需要额外的 OR
项来匹配 some string
.
的任一侧(或两侧)都没有文本的情况
最后,如果 'some string' 在 columnname
中相对少见,那么下面更长的查询实际上可能更快,因为它只会对少数值进行多次 GLOB
评估:
SELECT * FROM tablename where
columnname GLOB '*some string*' AND (
columnname GLOB '[^a-zA-Z0-9_]some string[^a-zA-Z0-9_]' OR
columnname GLOB 'some string[^a-zA-Z0-9_]' OR
columnname GLOB '[^a-zA-Z0-9_]some string' OR
columnname GLOB 'some string');
我想实现以下(全文搜索),
SELECT * FROM tablename where columnname REGEXP '[[:<:]]some string[[:>:]]'
我只对全文列中的确切字符串(不仅仅是单词)感兴趣。
我一直在 MySQL 中使用上面的 SQL,现在将大部分代码迁移到 android 应用程序。
但我一直在查看各种帖子,其中提到 Android Sqlite 不支持 REGEXP(例如:link1, link2, link3)。
有没有办法在 Android 中启用 REGEXP?
如果没有,上面的SQL有没有其他选择?
谢谢,
编辑: 目前我在 Android,
中使用 REGEXP 时收到以下异常android.database.sqlite.SQLiteException: no such function: REGEXP (code 1):...
我知道我们可以使用 GLOB 和 LIKE(或者甚至可以是 MATCH)。 columnname REGEXP '[[:<:]]somestring[[:>:]]'
如何转换为利用GLOB
and/or LIKE
and/or MATCH
?
解决方案 1:
在
SELECT * FROM tablename where
(columnname GLOB '*some string*' OR columnname GLOB '*Some string*') AND
(
(
(columnname GLOB '*[^a-zA-Z0-9_]some string[^a-zA-Z0-9_]*' AND
columnname GLOB '*some string[^a-zA-Z0-9_]*' AND
columnname GLOB '*[^a-zA-Z0-9_]some string*')
OR
(columnname GLOB '*[^a-zA-Z0-9_]Some string[^a-zA-Z0-9_]*' AND
columnname GLOB '*Some string[^a-zA-Z0-9_]*' AND
columnname GLOB '*[^a-zA-Z0-9_]Some string*')
)
)
GLOB
区分大小写所以我有一个额外的 OR
解决方案 2:处理大小写不敏感
SELECT * FROM tablename where
(columnname GLOB '*[sS][oO][mM][eE] [sS][tT][rR][iI][nN][gG]*') AND
(
(
columnname GLOB '*[^a-zA-Z0-9_][sS][oO][mM][eE] [sS][tT][rR][iI][nN][gG][^a-zA-Z0-9_]*' AND
columnname GLOB '*[sS][oO][mM][eE] [sS][tT][rR][iI][nN][gG][^a-zA-Z0-9_]*' AND
columnname GLOB '*[^a-zA-Z0-9_][sS][oO][mM][eE] [sS][tT][rR][iI][nN][gG]*')
)
要实际支持 REGEXP
,您必须添加自己的 regexp() user function。
This link 可能会帮助您了解如何为 Android 创建用户定义的函数——但这并不简单。
如果您的模式非常简单,GLOB operator 可能就足够了。
例如,要执行与此 MYSQL 查询等效的搜索:
SELECT * FROM tablename where columnname REGEXP '[[:<:]]some string[[:>:]]'
你可以在 SQLite 中试试这个:
SELECT * FROM tablename where
columnname GLOB '[^a-zA-Z0-9_]some string[^a-zA-Z0-9_]' OR
columnname GLOB 'some string[^a-zA-Z0-9_]' OR
columnname GLOB '[^a-zA-Z0-9_]some string' OR
columnname GLOB 'some string';
上面的查询使用了这样一个事实,即在 MYSQL 中,单词字符被定义为字母数字字符或下划线。还需要额外的 OR
项来匹配 some string
.
最后,如果 'some string' 在 columnname
中相对少见,那么下面更长的查询实际上可能更快,因为它只会对少数值进行多次 GLOB
评估:
SELECT * FROM tablename where
columnname GLOB '*some string*' AND (
columnname GLOB '[^a-zA-Z0-9_]some string[^a-zA-Z0-9_]' OR
columnname GLOB 'some string[^a-zA-Z0-9_]' OR
columnname GLOB '[^a-zA-Z0-9_]some string' OR
columnname GLOB 'some string');