SQLite FTS5 Match 不返回任何内容

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。

Ano*_*ard 6

FTS5 表仍需要填充。这包括外部内容案例。从文档中:

用户仍然有责任确保外部内容 FTS5 表的内容与内容表保持最新。一种方法是使用触发器。例如:

-- 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;
Run Code Online (Sandbox Code Playgroud)

因此,您可以在填充主表之前创建表和触发器,或者在测试用例中,在创建 FTS 表之后,您可以运行如下查询来首次填充 FTS 表:

INSERT INTO test_fts SELECT * FROM test;
Run Code Online (Sandbox Code Playgroud)

然后您的查询将按预期工作。

  • 谢谢你,这有效。但我不明白的是,为什么当我通过“SELECT * FROM test_fts”从中查询所有内容时,即使我没有用数据填充它,它实际上也会返回所有内容。 (2认同)
  • @ifbamoq看起来它会在创建主表时自动填充主表,但不会填充一些辅助表,例如“*_data”,它需要实际查找内容。然后,当您执行 INSERT 时,它会填充这些表(即使实际上没有新条目插入到您所说的要插入的表中)。如果这不是一个错误,那么默认行为真的很奇怪(据我所知,没有记录)。 (2认同)