使用没有列名的视图的SQLite FTS4外部内容

问题描述 投票:0回答:2

我正在使用FTS4sqlite 3.8.10,我正在尝试设置这样的架构:

CREATE TABLE Test (name TEXT);
CREATE VIEW TestView as SELECT name FROM Test;
CREATE VIRTUAL TABLE TestFTS using FTS4(content="TestView", name);

在这个玩具示例中,我有一个简单的表,Test和一个视图,TestView,相当于该表。我从视图中创建了FTS4索引TestFTS

然后我填写一些数据如下:

INSERT INTO Test VALUES ('bob');
INSERT INTO Test VALUES ('bill');
INSERT INTO Test VALUES ('jane');
INSERT INTO TestFTS(TestFTS) VALUES ('rebuild');

到现在为止还挺好。现在我想查询我的数据,例如:

SELECT name FROM TestFTS WHERE name MATCH "b*";

这应该返回两行:

短发

法案

相反,它返回一行,该行为空。如果我查询TestFTS表中的所有数据,那么我可以看到值,但显然如果我不能做MATCH类型查询它没有多大用处:

SELECT name FROM TestFTS;

短发

法案

知道为什么SQLite在没有列名的外部内容MATCHs上使用VIEW查询时没有返回数据,甚至没有返回正确的行数?

====

更新:我尝试使用sqlite 3.13与命名列视图,我看到同样的问题。

sqlite fts4
2个回答
2
投票

documentation说:

当FTS表上的用户查询需要docid以外的列值时,FTS会尝试从内容表中行的相应列读取请求的值,其rowid值等于当前的FTS docid。

因此视图必须包含一个名为rowid的唯一列,该列对应于FTS表的docid


0
投票

视图需要一个名为rowid的列。我还不够。请注意:SQLite网站上针对External Content Tables的示例具有误导性:

INSERT INTO t3(docid, b, c) SELECT id, b, c FROM t2;

使用和id列适用于普通表,但不适用于视图。您需要使用rowid:

INSERT INTO t3(docid, b, c) SELECT id rowid, b, c FROM t2;

基于SQLite文档示例的SQLite 3.11的完整控制台示例。

使用视图不起作用:

$ sqlite3 does_not_work.db;
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite> CREATE TABLE t2(id INTEGER PRIMARY KEY, a, b, c);
sqlite> CREATE VIEW t2_v AS SELECT id, a, b, c FROM t2;
sqlite> CREATE VIRTUAL TABLE t3 USING fts4(content="t2_v", b, c);
sqlite> INSERT INTO t2 VALUES(2, 'a b', 'c d', 'e f');
sqlite> INSERT INTO t2 VALUES(3, 'g h', 'i j', 'k l');
sqlite> INSERT INTO t3(docid, b, c) SELECT id, b, c FROM t2_v;
sqlite> SELECT * FROM t3 WHERE t3 MATCH 'k';
|
sqlite> .exit

但是在创建视图时为id设置rowid的列别名有效:

sqlite3 works.db;
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite> CREATE TABLE t2(id INTEGER PRIMARY KEY, a, b, c);
sqlite> CREATE VIEW t2_v AS SELECT id rowid, a, b, c FROM t2;
sqlite> CREATE VIRTUAL TABLE t3 USING fts4(content="t2_v", b, c);
sqlite> INSERT INTO t2 VALUES(2, 'a b', 'c d', 'e f');
sqlite> INSERT INTO t2 VALUES(3, 'g h', 'i j', 'k l');
sqlite> INSERT INTO t3(docid, b, c) SELECT rowid, b, c FROM t2_v;
sqlite> SELECT * FROM t3 WHERE t3 MATCH 'k';
i j|k l
sqlite> 

使用普通表有效:

$ sqlite3 also_works.db;
SQLite version 3.11.0 2016-02-15 17:29:24
Enter ".help" for usage hints.
sqlite> CREATE TABLE t2(id INTEGER PRIMARY KEY, a, b, c);
sqlite> CREATE VIRTUAL TABLE t3 USING fts4(content="t2", b, c);
sqlite> INSERT INTO t2 VALUES(2, 'a b', 'c d', 'e f');
sqlite> INSERT INTO t2 VALUES(3, 'g h', 'i j', 'k l');
sqlite> INSERT INTO t3(docid, b, c) SELECT id, b, c FROM t2;
sqlite> SELECT * FROM t3 WHERE t3 MATCH 'k';
i j|k l
sqlite> 
© www.soinside.com 2019 - 2024. All rights reserved.