我可以在FTS查询中使用AND语句吗?

时间:2016-12-16 22:52:57

标签: sqlite full-text-search fts3

在虚拟表中使用索引列执行带有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';

类型状态在虚拟表中被编入索引。

1 个答案:

答案 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