2016-12-16 69 views
1

在虛擬表的索引列上使用AND語句執行查詢時,仍有可能在SQLite中享受FTS3/4的好處嗎?例如:我可以在FTS查詢中使用AND語句嗎?

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'; 

其中列類型狀態在虛擬表進行索引。

回答

2

FTS表中的所有列都是文本列,並且是FTS索引的; documentation說:

如果作爲CREATE VIRTUAL TABLE語句的一部分顯式爲FTS表提供列名,那麼可以爲每列選擇性地指定一個數據類型名稱。這是純粹的語法糖,所提供的類型名稱不被FTS或SQLite內核用於任何目的。通過ROWID

  • 查詢:

你不應該做這樣type=1搜索上的FTS表:

FTS表可以有效地利用兩種不同形式的SELECT語句進行查詢。如果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

    +0

    感謝您的回答,這正是我一直在尋找的!在將其標記爲答案之前,您是否也可以向我展示如何修改該查詢以僅包含一部分docid,如50-100之間的docid。我問的原因是我正在創建一個可滾動列表,每次只需要加載大約50行。謝謝! – user3367265

    +0

    這將是一個完全不同的問題。 –

    +0

    好吧,如果我要發表另外一個問題,在我給你正確的答案後,你認爲你可以幫助我,那麼我也會給你正確的答案嗎?謝謝! – user3367265

    相關問題