SQLite FTS5删除行后仍出现在MATCH查询结果的问题
问题描述
我创建了如下Tests表:
CREATE TABLE Tests (col1 INTEGER, col2 INTEGER, col3 INTEGER, col4 INTEGER, col5 INTEGER);
并插入以下数据:
INSERT INTO Tests (col1, col2, col3, col4, col5) VALUES (1, 2, 3, 4, 5); INSERT INTO Tests (col1, col2, col3, col4, col5) VALUES (6, 7, 8, 9, 10); INSERT INTO Tests (col1, col2, col3, col4, col5) VALUES (11, 12, 13, 14, 15); INSERT INTO Tests (col1, col2, col3, col4, col5) VALUES (16, 17, 18, 19, 20);
接着为其创建FTS5虚拟表:
CREATE VIRTUAL TABLE TestFTS5 USING fts5(col1, col2, col3, tokenize = "ascii separators ' '", content=''); INSERT INTO TestFTS5 (rowid, col1, col2, col3) SELECT DISTINCT rowid, col1, col2, col3 FROM Tests;
未执行任何删除操作时,执行查询:
SELECT COUNT(1) FROM TestFTS5 WHERE TestFTS5 MATCH '1* OR 7';
返回结果为4。但在执行FTS5表的删除操作后:
INSERT INTO TestFTS5 (TestFTS5, rowid, col1, col2, col3) VALUES ('delete', 1, NULL, NULL, NULL);
上述查询仍返回4。我尝试同时删除主表和FTS5表的行:
DELETE FROM Tests WHERE rowid = 4; INSERT INTO TestFTS5 (TestFTS5, rowid, col1, col2, col3) VALUES ('delete', 4, NULL, NULL, NULL);
但查询结果依旧为4。我曾怀疑是事务未提交,保存更改后问题仍存在。注意到每次执行'delete'插入操作后,TestFTS5_docsize表中对应行ID的记录会消失,但删除的行仍出现在查询结果中。请问我操作哪里有误?我严格按照'delete'的文档说明执行,但删除的行仍被包含在结果里。
问题解决
你的核心问题是无内容模式下的FTS5删除语法错误:
当FTS5虚拟表通过content=''设置为无内容模式时,执行删除操作不需要指定除rowid外的其他列。你当前的删除语句额外添加了col1、col2、col3字段并赋值为NULL,这会导致FTS5无法正确识别删除指令,索引中的数据并未被真正移除。
正确的删除语句格式
对于无内容模式的FTS5表,删除指定rowid的记录,只需执行:
INSERT INTO TestFTS5 (TestFTS5, rowid) VALUES ('delete', 1);
验证修改结果
- 执行正确的删除语句删除
rowid=1后,再执行查询:
SELECT COUNT(1) FROM TestFTS5 WHERE TestFTS5 MATCH '1* OR 7';
此时结果应为3(原匹配的行2、行3、行4)。
- 若再删除
rowid=4:
INSERT INTO TestFTS5 (TestFTS5, rowid) VALUES ('delete', 4);
查询结果会变为2(仅行2、行3匹配)。
补充说明
- 无内容模式下,FTS5仅存储索引数据,不保存原始列内容,因此删除时只需指定
rowid即可定位并移除对应索引条目。 - 若FTS5表关联了实际内容表(即
content参数指定为某个表名),则可以直接使用DELETE FROM TestFTS5 WHERE rowid=xxx语法,FTS5会自动同步索引和内容表数据。
内容的提问来源于stack exchange,提问作者user19610681
相关产品推荐
相关产品推荐

