Android 中使用 Sqlite 全文搜索对非英文字符的 Unicode 支持

Sur*_*gch 7 sqlite unicode android full-text-search

滚动到最后跳过解释。

背景

在我的 Android 应用程序中,我想使用非英语 Unicode 文本字符串来搜索存储在 SQLite 数据库中的文本文档/字段中的匹配项。我了解到(所以我认为)我需要做的是使用 fts3/fts4实现全文搜索,这就是我过去几天一直在学习的内容。Android 支持 FTS,如文档存储和搜索数据和博客文章Android 快速提示:使用 SQLite FTS 表中所示

问题

一切看起来都不错,但后来我阅读了 2012 年 3 月的博客文章Android 上 SQLite 全文搜索的遗憾状态,其中说

构建全文搜索索引的第一步是将文本内容分解为单词,也就是标记。然后将这些标记输入一个特殊的索引,让 SQLite 基于一个标记(或一组标记)执行非常快速的搜索。

SQLite 有两个内置的标记器,它们都只考虑由美国 ASCII 字符组成的标记。所有其他非美国 ASCII 字符都被视为空格。

之后,我还找到了@CL 的这个 StackOverflow 答案(根据标签和声誉,他似乎是 SQLite 专家)回答有关将越南字母与不同变音符号匹配的问题:

您必须使用可以处理 Unicode 字符(即 ICU 或 UNICODE61)的标记器创建 FTS 表。

请注意,这些分词器可能并非在所有 Android 版本上都可用,并且 Android API 不会公开任何用于添加用户定义的分词器的函数。

这个 2011 SO answer似乎证实了 Android 不支持超出两个基本simpleporter一个的标记器。

这是 2015 年。这种情况有任何更新吗?我需要为每个使用我的应用程序的人提供全文搜索支持,而不仅仅是拥有新手机的人(即使最新的 Android 版本现在确实支持它)。

潜在的部分解决方案?

我发现很难相信 FTS 对 Unicode 根本不起作用。该文档simple标记者说:

术语是合格字符的连续序列,其中合格字符是所有字母数字字符和所有 Unicode 代码点值大于或等于 128 的字符。将文档拆分为术语时,将丢弃所有其他字符。它们唯一的贡献是分隔相邻的术语。(强调)

这让我希望 Android 仍然可以支持一些基本的 Unicode 功能,即使不支持大写和变音符号(以及具有不同 Unicode 代码点的各种其他等效字母形式)。

我的主要问题

如果我只使用由空格分隔的文字 Unicode 字符串标记,我可以在 Android 中使用带有非英语 Unicode 文本(代码点 > 128)的 SQLite FTS 吗?(也就是说,我正在搜索文本中出现的确切字符串。)

更新

Sur*_*gch 5

补充答案

我最终按照@CL 的建议进行了操作,并且能够使用 Unicode 成功实现全文搜索。这些是我遵循的基本步骤:

  1. 用空格字符替换所有不属于单词的 Unicode 字符 (>=128)。
  2. (可选)用更通用的字符替换特定字符。例如,?èé都可以替换为e(如果需要这种广义搜索)。这不是必需的,但如果您不这样做,则搜索é将仅返回带有 的文档é,而搜索e将仅返回带有e(而不是é)的文档。
  3. 使用在步骤 1 和 2 中创建的修改后的文本填充虚拟 FTS 表。
  4. 用未修改的文本填充普通表格。当然,架构和文档数量必须与创建 FTS 表时相同。
  5. 使用外部内容表将虚拟 FTS 表与您的普通文本表/列链接,这样您就不会存储修改文本的副本,只存储从该文本创建的文档 ID。

有关如何创建 FTS 表并将其链接到普通表的说明,请阅读Android 中的全文搜索示例。这花了很长时间才弄明白,但最终它即使对大量文档也进行了非常快速的全文搜索。

如果您需要更多详细信息,请在下面发表评论。


CL.*_*CL. 3

Unicode 字符的处理方式与“普通”字母类似,因此您可以在 FTS 数据和搜索词中使用它们。(前缀搜索也应该有效。)

\n\n

问题在于 Unicode 字符没有标准化,即所有字符都被视为字母(即使它们实际上是标点符号 (\xe2\x80\x95\xe2\x80\xa0),或其他非字母字符 (\xe2\ x98\xba\xe2\x99\xab)),并且大写/小写不会合并,并且变音符号不会被删除。
\n如果您想正确处理这些情况,则必须在将文档插入数据库之前以及使用搜索词之前手动执行这些规范化。

\n


归档时间:

查看次数:

3526 次

最近记录:

9 年,6 月 前