4

我在启用 FTS 的 SQLite 数据库上看到一些奇怪的行为。我有一个名为的表fingerprints,其中包含一个名为scan. 扫描条目是长字符串,如下所示:

00:13:10:d5:69:88_-58;0c:85:25:68:b4:30_-75;0c:85:25:68:b4:34_-76;0c:85:25:68:b4:33_-76;0c:85:25:68:b4:31_-76;0c:85:25:68:b4:35_-76;00:23:eb:ad:f6:00_-87; etc

它代表 MAC 地址和信号强度。现在我想在表上进行字符串匹配并尝试匹配例如 MAC 地址:

SELECT _id FROM fingerprints WHERE scan MATCH "00:13:10:d5:69:88";

由于某种原因,这会返回许多没有指定字符串的行。我要尝试匹配的第二件事是

SELECT _id FROM fingerprints WHERE scan MATCH "00:13:10:d5:69:88_-58";

这将返回与以前相同的行,并且是完全错误的。

SQLite 是否: _ -以任何特殊方式处理字符?

谢谢

4

1 回答 1

4

您所看到的是 FTS对您的数据进行标记的效果。

全文搜索不适用于未处理的长字符串,它将您的数据(和您的搜索词)拆分为单词并单独索引它们。默认分词器使用所有字母数字字符和代码点 >128 的所有字符作为单词,并使用其余字符(例如,如您所见: _ -)作为单词边界。

换句话说,您的搜索00:13:10:d5:69:88将搜索包含单词00and1310andd5以及69and88

您可以验证此行为;

sqlite> CREATE VIRTUAL TABLE simple USING fts3(tokenize=simple);
sqlite> INSERT INTO simple VALUES('00:13:10:d5:69:88');
sqlite> SELECT * FROM simple WHERE simple MATCH '69:10';

-> 00:13:10:d5:69:88

编辑:显然 SQLite 比我最初认为的要聪明,您可以使用短语查询(从链接目标向下滚动页面)来查找单词序列,这将解决您的问题。通过用双引号 (") 将空格(或其他单词分隔符)分隔的术语序列括起来来指定短语查询。

sqlite> SELECT * FROM simple WHERE simple MATCH '"69:10"';

-> No match

sqlite> SELECT * FROM simple WHERE simple MATCH '"69 88"';

-> 00:13:10:d5:69:88

sqlite> SELECT * FROM simple WHERE simple MATCH '"69:88"';

-> 00:13:10:d5:69:88
于 2013-02-19T04:14:45.270 回答