SQLite FTS表是否需要手动填充?

SQLite FTS表是否需要手动填充?,sqlite,full-text-search,fts4,Sqlite,Full Text Search,Fts4,SQLite FTS的文档说明应使用INSERT、UPDATE、DELETE等填充和更新FTS表 这就是我所做的——添加行、删除行等等,但最近我注意到,只要创建FTS表,它就会使用源数据自动填充。我是这样创建的: CREATE VIRTUAL TABLE notes_fts USING fts4(content="notes", notindexed="id", id, title, body) 如果我向“notes”表中添加一行,它也会自动添加到notes_fts中。我想这就是虚拟表 但是,

SQLite FTS的文档说明应使用INSERT、UPDATE、DELETE等填充和更新FTS表

这就是我所做的——添加行、删除行等等,但最近我注意到,只要创建FTS表,它就会使用源数据自动填充。我是这样创建的:

CREATE VIRTUAL TABLE notes_fts USING fts4(content="notes", notindexed="id", id, title, body)
如果我向“notes”表中添加一行,它也会自动添加到notes_fts中。我想这就是虚拟表

但是,为什么有一章是关于填充FTS表的?还有什么意义呢?例如,如果我删除一行,如果它仍然在源表中,它就会返回


你知道吗?FTS真的需要填充吗?

进一步阅读后,我发现FTS表确实需要手动与内容表保持同步。运行
CREATE VIRTUAL TABLE
调用时,会自动填充FTS表,但在这之后,必须手动执行删除、插入和更新

在我的例子中,我使用了以下触发器:

CREATE VIRTUAL TABLE notes_fts USING fts4(content="notes", notindexed="id", id, title, body

CREATE TRIGGER notes_fts_before_update BEFORE UPDATE ON notes BEGIN
    DELETE FROM notes_fts WHERE docid=old.rowid;
END

CREATE TRIGGER notes_fts_before_delete BEFORE DELETE ON notes BEGIN
    DELETE FROM notes_fts WHERE docid=old.rowid;
END

CREATE TRIGGER notes_after_update AFTER UPDATE ON notes BEGIN
    INSERT INTO notes_fts(docid, id, title, body) SELECT rowid, id, title, body FROM notes WHERE is_conflict = 0 AND encryption_applied = 0 AND new.rowid = notes.rowid;
END

CREATE TRIGGER notes_after_insert AFTER INSERT ON notes BEGIN
    INSERT INTO notes_fts(docid, id, title, body) SELECT rowid, id, title, body FROM notes WHERE is_conflict = 0 AND encryption_applied = 0 AND new.rowid = notes.rowid;
END;

要删除条目

-- Insert a row with rowid=14 into the fts5 table.
INSERT INTO ft(rowid, a, b, c) VALUES(14, $a, $b, $c);

-- Remove the same row from the fts5 table.
INSERT INTO ft(ft, rowid, a, b, c) VALUES('delete', 14, $a, $b, $c);

基于修改后的虚拟表重建

INSERT INTO ft(ft) VALUES('rebuild');

我不知道旧版本的情况,但带有外部内容表的FTS5需要在内容表中添加、删除或更改行时更新fts表,以便更新索引。也许有一些触发点是你忽略了的?在评论中留下错误是一个很好的做法。我无法在LukaszSzozda处复制它,该消息实际上是相关触发器中的一个错误。不知怎的,Sqlite没有显示触发器的名称,这让它很混乱。
INSERT INTO ft(ft) VALUES('rebuild');