如何查找 FTS5 和 MATCH 之间的记录?

Posted

技术标签:

【中文标题】如何查找 FTS5 和 MATCH 之间的记录?【英文标题】:How to find records BETWEEN with FTS5 and MATCH? 【发布时间】:2017-01-24 08:50:19 【问题描述】:

如何使用 FTS5 表在 SQLite3 数据库中搜索(价格)范围?

这是一个高度简化的示例表:

CREATE VIRTUAL TABLE fruits USING fts5 (id, name, price);
INSERT INTO fruits (id,name,price) VALUES (1, 'Apple with A', 5);
INSERT INTO fruits (id,name,price) VALUES (2, 'Pineapple with B', 10);
INSERT INTO fruits (id,name,price) VALUES (3, 'Cucumber with C', 20);
INSERT INTO fruits (id,name,price) VALUES (4, 'Melon with D', 25);
INSERT INTO fruits (id,name,price) VALUES (5, 'Kiwi with E', 30);
INSERT INTO fruits (id,name,price) VALUES (6, 'Cucumber with F', 35);
INSERT INTO fruits (id,name,price) VALUES (7, 'Cucumber with G', 40);

以下命令返回 Cucumber 的预期两条记录 3 和 7:

SELECT * FROM fruits WHERE fruits MATCH 'name:Cucumber AND (price:20 OR price:40)';

如何搜索价格范围为 20 到 40 的 Cucumbers(包括上例中的记录 6)?如果我尝试一下

SELECT * FROM fruits WHERE fruits MATCH 'name:Cucumber AND (price: BETWEEN 20 AND 40)';

SELECT * FROM fruits WHERE fruits MATCH 'name:Cucumber AND (price: BETWEEN 19 AND 41)';

我根本没有得到任何结果(或错误消息)。一个查询不能同时使用 MATCH 和 BETWEEN 吗?


此外: 为什么命令

SELECT * FROM fruits WHERE fruits MATCH 'name:C';

只返回一条记录 (id: 3) 而不是 3、6 和 7,假设 'Cucumber' 中的 C 也会被找到,而不仅仅是 'with C' 中的 C?

【问题讨论】:

【参考方案1】:

FTS 表将所有内容存储为文本;在 FTS 表中包含 idprice 列是没有意义的。

对 FTS 表唯一有效的查询是搜索单词(以及通过内部 docid 进行查找)。

您不应将 FTS 表视为表,而应将其视为 索引。将其他数据保存在“真实”表中,并对该表执行任何其他查询:

SELECT *
FROM fruits
WHERE id IN (SELECT docid
             FROM fruits_fts
             WHERE fruits_fts MATCH 'Cucumber')
  AND price BETWEEN 20 AND 40;

要搜索以C 开头的单词,您必须使用prefix search。

【讨论】:

还有一种方法可以将范围过滤器添加到分数中吗?所以排名只由这里的 MATCH 子句决定?! @nhaberl 要提出问题,请使用"" button。

以上是关于如何查找 FTS5 和 MATCH 之间的记录?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Peewee 和 SQLite 的 FTS5 中使用 trigram tokenizer/similarity 选项?

如何使用带有 Python 3.7 的 sqlite3 python 模块的 FTS5 扩展?

Sqlite FTS5:使用 Trigram Tokenizer 进行子字符串匹配

升级 Wagtail 后如何解决 fts5 错误

如何在 Ubuntu 16.04 上将 FTS5 扩展与带有 Python 3.7 的 sqlite3 python 模块一起使用?

MySQL - 如何查找日期在开始日期到结束日期之间的记录