滚动到末尾以跳过说明。
背景
在我的 Android 应用程序中,我想使用非英语 Unicode 文本字符串来搜索存储在 SQLite 数据库中的文本文档/字段中的匹配项。我了解到(所以我认为)我需要做的是实施一个使用 fts3/fts4 进行全文搜索 http://www.sqlite.org/fts3.html#section_1,这就是我这几天一直在努力学习的内容。 Android 支持 FTS,如文档所示存储和搜索数据 http://developer.android.com/training/search/search.html并在博客文章中Android 快速提示:使用 SQLite FTS 表 http://blog.andresteingress.com/2011/09/30/android-quick-tip-using-sqlite-fts-tables/.
Problem
一切看起来都不错,但后来我读了 2012 年 3 月的博客文章Android 上 SQLite 全文搜索的遗憾现状 http://kmansoft.com/2012/03/17/the-sorry-state-of-sqlite-full-text-search-on-android/,其中说
建立全文搜索索引的第一步是分解
将文本内容转换为单词,也称为标记。那么这些令牌就是
输入一个特殊的索引,让 SQLite 执行速度非常快
基于一个标记(或一组标记)的搜索。
SQLite 有两个内置的分词器 http://www.sqlite.org/fts3.html#tokenizer,并且他们都只考虑 token
由 US ASCII 字符组成。所有其他非 US ASCII 字符
被视为空白。
之后我还发现这个 StackOverflow 答案 https://stackoverflow.com/a/17399384/3681880 by @CL. https://stackoverflow.com/users/11654/cl(根据标签和声誉,他似乎是 SQLite 专家)回答有关将越南语字母与不同变音符号匹配的问题:
您必须使用可以处理 Unicode 的分词器创建 FTS 表
字符,即 ICU 或 UNICODE61。
请注意,这些标记器可能不适用于所有
Android 版本,并且 Android API 不公开任何
用于添加用户定义的标记器的函数。
这个2011年的答案 https://stackoverflow.com/a/8183890/3681880似乎证实 Android 不支持超出两个基本的标记器simple
and porter
ones.
现在是2015年了,这种情况有什么更新吗?我需要为使用我的应用程序的每个人提供全文搜索支持,而不仅仅是拥有新手机的人(即使最新的 Android 版本现在确实支持它)。
潜在的部分解决方案?
我很难相信 FTS 根本不能与 Unicode 一起使用。这文档 http://www.sqlite.org/fts3.html#tokenizer为了simple
分词器说
术语是符合条件的字符的连续序列,其中符合条件的
字符均为字母数字字符和所有字符
Unicode 代码点值大于或等于 128。所有其他
将文档拆分为术语时,字符将被丢弃。他们的
唯一的贡献是分离相邻的术语。(强调已添加)
这给了我希望,即使不支持大写和变音符号(以及具有不同 Unicode 代码点的各种其他等效字母形式)之类的内容,Android 中仍然可以支持一些基本的 Unicode 功能。
我的主要问题
如果我仅使用以空格分隔的文字 Unicode 字符串标记,我可以在 Android 中将 SQLite FTS 与非英语 Unicode 文本(代码点 > 128)一起使用吗? (也就是说,我正在搜索文本中出现的确切字符串。)
Updates
- The unicode61 分词器 https://www.sqlite.org/fts3.html#unicode61在 SQLite 版本 3.7.13 中可用。该分词器支持“完整的 unicode 大小写折叠”和“识别 unicode 空格和标点字符”。Android Lollipop(API 20+)使用 SQLite 3.8 https://stackoverflow.com/questions/2421189/version-of-sqlite-used-in-android/4377116#4377116.