ifb*_*moq 3 sqlite full-text-search fts3 fts4 fts5
我有一个 SQLite3 表:
CREATE TABLE "test" (
"title" TEXT,
"shortdesc" TEXT,
"longdesc" TEXT,
"id" TEXT,
PRIMARY KEY("id")
);
Run Code Online (Sandbox Code Playgroud)
我在里面插入任何东西:
INSERT INTO test (id, title, shortdesc, longdesc) VALUES ("abc", "hello world", "this is a hello world", "a nice hello world article about hello worlds")
Run Code Online (Sandbox Code Playgroud)
然后我创建一个 FTS5 虚拟表:
CREATE VIRTUAL TABLE IF NOT EXISTS test_fts USING fts5 (
id,
title,
shortdesc,
longdesc,
content=test
);
Run Code Online (Sandbox Code Playgroud)
所以我检查虚拟表中的数据:
一切看起来都很好...现在我尝试使用MATCH
来查找文章:
SELECT * FROM test_fts WHERE test_fts MATCH 'hello'
Run Code Online (Sandbox Code Playgroud)
...我没有得到任何结果。显然,我展示的这个数据库只是一个示例,实际数据库也会发生同样的情况。我在不同的计算机(和不同的客户端)上尝试过,我还检查了 FTS5 是否已启用并在其中编译,并且PRAGMA compile_options
是否ENABLE_FTS5
存在,这意味着它已启用。FTS3 和 4 也会发生同样的情况。
那么我错过了什么?SQLite 版本是 3.36.0。
FTS5 表仍需要填充。这包括外部内容案例。从文档中:
用户仍然有责任确保外部内容 FTS5 表的内容与内容表保持最新。一种方法是使用触发器。例如:
Run Code Online (Sandbox Code Playgroud)-- Create a table. And an external content fts5 table to index it. CREATE TABLE tbl(a INTEGER PRIMARY KEY, b, c); CREATE VIRTUAL TABLE fts_idx USING fts5(b, c, content='tbl', content_rowid='a'); -- Triggers to keep the FTS index up to date. CREATE TRIGGER tbl_ai AFTER INSERT ON tbl BEGIN INSERT INTO fts_idx(rowid, b, c) VALUES (new.a, new.b, new.c); END; CREATE TRIGGER tbl_ad AFTER DELETE ON tbl BEGIN INSERT INTO fts_idx(fts_idx, rowid, b, c) VALUES('delete', old.a, old.b, old.c); END; CREATE TRIGGER tbl_au AFTER UPDATE ON tbl BEGIN INSERT INTO fts_idx(fts_idx, rowid, b, c) VALUES('delete', old.a, old.b, old.c); INSERT INTO fts_idx(rowid, b, c) VALUES (new.a, new.b, new.c); END;
因此,您可以在填充主表之前创建表和触发器,或者在测试用例中,在创建 FTS 表之后,您可以运行如下查询来首次填充 FTS 表:
INSERT INTO test_fts SELECT * FROM test;
Run Code Online (Sandbox Code Playgroud)
然后您的查询将按预期工作。