如何停止。在 SQLite FTS4 中被视为分隔符

Posted

技术标签:

【中文标题】如何停止。在 SQLite FTS4 中被视为分隔符【英文标题】:How to stop . being treated as a separator in SQLite FTS4 【发布时间】:2013-04-18 10:19:46 【问题描述】:

我希望能够在 SQLite 中使用 FTS4 搜索像 2.3 这样的数字,但是 .被视为令牌边界。除了编写完整的定制标记器之外,还有其他方法可以排除 .来自令牌边界字符列表?

能够搜索十进制数字似乎是一个常见的用例,但我在 SO / Google 上找不到任何相关内容。我目前最好的解决方案是全部替换。文本中带有已知(长)字母串的字符,并在每次搜索时相应地替换...

彼得

【问题讨论】:

【参考方案1】:

其实你不需要自己写分词器。

“简单”标记器允许自定义分隔符,但它是一个未记录的功能。

按如下方式创建您的 FTS 表,SQLite 将仅对“”(空格)和“#”(哈希)字符进行标记:

CREATE VIRTUAL TABLE documents USING fts4(title, content, tokenize=simple '' '# ');

在 2012 年 here 的 SQLite 邮件列表中有关于此功能的讨论。 SQLite 中支持该功能的源代码为here。

从邮件列表中引用关于其缺乏文档的内容:

“可能的原因是我们忘记了这个功能甚至存在。 它似乎存在于简单的标记器中,没有改变,因为 早在 2006 年首次引入 FTS1。”

关于使用该功能是否安全的引用:

"但是现在代码里放了这么久我们都不敢改 因为害怕破坏长期建立的程序。”

...但是也有人提到该功能不太可能经过彻底测试。

我刚刚向 SQLite 用户邮件列表发送了电子邮件,询问是否可以记录此功能。

更新:我要补充的一件事是,我们发现如果像这样将“*”或“-”等字符配置为分隔符,那么它们也会从 中的 FTS MATCH 子句中删除查询。因此,虽然这适用于“。”等,它不能用于在FTS MATCH中也是特殊字符的字符。

【讨论】:

非常感谢您的回答。原始代码已完成并已部署,但下次我会尝试您的建议 :-)【参考方案2】:

您不需要编写自己的分词器:一些内置分词器允许您在创建表时指定某些字符应该或不应该被视为单词字符。例如,unicode61 标记器(参见FTS3 docs,您可能必须在构建时启用对它的支持)允许您传递tokencharsseparators 参数(在source 中查看)。

在你的情况下,我相信你可以使用这样的东西:

CREATE VIRTUAL TABLE whatever USING fts4(
    columns,

    tokenize=unicode61 "tokenchars=."
);

【讨论】:

【参考方案3】:

标记器定义了标记是什么,因此您确实需要编写自己的标记。

您可以搜索短语"2 3",它会找到带有任意分隔符的数字 2 和 3。

【讨论】:

嗨 CL - 我认为你是对的。我希望有人以前可能已经解决了这个问题,但我想在文本中搜索数字并不常见。我通过在标记化之前将 (\d+)\.(\d+) 正则表达式转换为 $1XXUNIQUEPHRASEXX$2 来解决我的目的,并对我的搜索文本执行相同的操作。工作正常,但感觉 uuuuugggggllly。由于本地化(相对于欧洲等),实际上很难正确完成。感谢您的回复 - 我很感激。

以上是关于如何停止。在 SQLite FTS4 中被视为分隔符的主要内容,如果未能解决你的问题,请参考以下文章

SQLite3 FTS4、MATCH 和 Android

SQLite、FTS、MATCH 和分隔列中的文本

SQLite3 FTS3/FTS4 匹配信息示例

需要调整我的 FTS4 SQLite 查询

FTS4 SQLITE 中的外部内容

带有 FTS4 表的 sqlite3:查询返回错误的行