上一節中的示例說明了使用簡單常量字串進行全文匹配。本節展示瞭如何搜尋表資料,並可選擇使用索引。
可以不使用索引進行全文搜尋。一個簡單的查詢,用於列印在其 body
欄位中包含單詞 friend
的每一行的 title
,是:
SELECT title FROM pgweb WHERE to_tsvector('english', body) @@ to_tsquery('english', 'friend');
由於所有這些單詞都會被簡化為相同的規範化詞元(lexeme),所以這也將找到相關詞,例如 friends
和 friendly
。
上面的查詢指定了使用 english
配置來解析和規範化字串。或者,我們也可以省略配置引數:
SELECT title FROM pgweb WHERE to_tsvector(body) @@ to_tsquery('friend');
此查詢將使用由 default_text_search_config 設定的配置。
一個更復雜的例子是選擇在 title
或 body
中包含 create
和 table
的十個最新文件:
SELECT title FROM pgweb WHERE to_tsvector(title || ' ' || body) @@ to_tsquery('create & table') ORDER BY last_mod_date DESC LIMIT 10;
為清晰起見,我們省略了 coalesce
函式的呼叫,而這些呼叫將需要找到在一個欄位中包含 NULL
的行。
儘管這些查詢在沒有索引的情況下也能工作,但對於大多數應用程式來說,這種方法太慢了,除了偶爾的臨時搜尋。全文搜尋的實際使用通常需要建立索引。
我們可以建立一個GIN索引(第 12.9 節)來加速全文搜尋。
CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', body));
請注意,這裡使用了 to_tsvector
的 2 引數版本。表示式索引(第 11.7 節)只能使用指定了配置名稱的文字搜尋函式。這是因為索引內容必須不受 default_text_search_config 的影響。如果受影響,索引內容可能不一致,因為不同的條目可能包含使用不同文字搜尋配置建立的 tsvector
,而且無法猜測哪個是哪個。這樣將無法正確轉儲和恢復索引。
因為上面的索引中使用了 to_tsvector
的兩個引數版本,所以只有使用相同的配置名稱和 to_tsvector
的兩個引數版本來引用的查詢才能使用該索引。也就是說,WHERE to_tsvector('english', body) @@ 'a & b'
可以使用該索引,但 WHERE to_tsvector(body) @@ 'a & b'
不能。這確保了索引只與建立索引條目時使用的配置相同才能被使用。
可以設定更復雜的表示式索引,其中配置名稱由另一個列指定,例如:
CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector(config_name, body));
其中 config_name
是 pgweb
表中的一個列。這允許在同一個索引中使用混合配置,同時記錄每個索引條目使用的配置。例如,如果文件集合包含不同語言的文件,這將很有用。同樣,旨在使用的查詢必須符合匹配模式,例如 WHERE to_tsvector(config_name, body) @@ 'a & b'
。
索引甚至可以連線列:
CREATE INDEX pgweb_idx ON pgweb USING GIN (to_tsvector('english', title || ' ' || body));
另一種方法是建立一個單獨的 tsvector
列來儲存 to_tsvector
的輸出。為了使此列與源資料自動保持同步,請使用儲存的生成列。此示例連線了 title
和 body
,並使用 coalesce
來確保當一個欄位為 NULL
時,另一個欄位仍會被索引:
ALTER TABLE pgweb ADD COLUMN textsearchable_index_col tsvector GENERATED ALWAYS AS (to_tsvector('english', coalesce(title, '') || ' ' || coalesce(body, ''))) STORED;
然後我們建立一個GIN索引來加速搜尋。
CREATE INDEX textsearch_idx ON pgweb USING GIN (textsearchable_index_col);
現在我們準備執行快速全文搜尋。
SELECT title FROM pgweb WHERE textsearchable_index_col @@ to_tsquery('create & table') ORDER BY last_mod_date DESC LIMIT 10;
與表示式索引相比,單獨列方法的優點之一是,為了使用索引,不必在查詢中顯式指定文字搜尋配置。如上面的示例所示,查詢可以依賴於 default_text_search_config
。另一個優點是搜尋速度更快,因為不必重新執行 to_tsvector
呼叫來驗證索引匹配。(這在使用 GiST 索引時比使用 GIN 索引更重要;參見 第 12.9 節。)然而,表示式索引方法設定起來更簡單,而且它需要的磁碟空間更少,因為 tsvector
表示沒有顯式儲存。
如果您在文件中看到任何不正確的地方、與您對特定功能的體驗不符或需要進一步澄清的內容,請使用此表單報告文件問題。