You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);

验证修改结果

  1. 执行正确的删除语句删除rowid=1后,再执行查询:
SELECT COUNT(1) FROM TestFTS5 WHERE TestFTS5 MATCH '1* OR 7';

此时结果应为3(原匹配的行2、行3、行4)。

  1. 若再删除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 16:36:23