在虚拟表中使用索引列执行带有AND语句的查询时,是否仍然可以在SQLite中享受FTS3 / 4的好处?例如:
SELECT title, ID, creationDate FROM documents WHERE type=1 AND status=2 AND searchableFields MATCHES '"john doe"';
OR
SELECT title, ID, creationDate FROM documents WHERE type=1 AND status=2 AND searchableFields CONTAINS 'john doe';
列类型和状态在虚拟表中被编入索引。
答案 0 :(得分:2)
FTS表中的所有列都是文本列,并且是FTS索引的; documentation说:
如果作为CREATE VIRTUAL TABLE语句的一部分为FTS表显式提供了列名,则可以为每列选择性地指定数据类型名称。这是纯粹的语法糖,FTS或SQLite核心不会出于任何目的使用提供的类型名称。
您不应该在FTS表上执行type=1
之类的搜索:
可以使用两种不同形式的SELECT语句有效查询FTS表:
- 按rowid查询。如果SELECT语句的WHERE子句包含“rowid =?”形式的子子句,其中?是一个SQL表达式,FTS能够使用等效的SQLite INTEGER PRIMARY KEY索引直接检索请求的行。
- 全文查询。如果SELECT语句的WHERE子句包含“MATCH?”形式的子句,FTS可以使用内置的全文索引将搜索限制为与指定为MATCH子句的右侧操作数的全文查询字符串匹配的文档。
如果这两种查询策略都不能使用,则FTS表上的所有查询都是使用整个表的线性扫描来实现的。如果表包含大量数据,这可能是一种不切实际的方法。
您不应该将FTS表视为表,而应将其视为索引。
如果要存储非文本数据,则应使用单独的普通表,并单独查询:
SELECT title, ID, creationDate
FROM documents
WHERE type=1
AND status=2
AND ID IN (SELECT docid
FROM documents_FTS
WHERE searchableFields MATCH '"john doe"');
为避免两次存储相同的数据,您可以使用contentless or external content tables。