前一節的範例說明了使用簡單常數字串進行全文比對。 本節說明如何搜尋表格資料,可選擇性地使用索引。
可以不使用索引進行全文檢索。 一個簡單的查詢,用於列印 title
欄位中,其 body
欄位包含單字 friend
的每一列的資料,查詢如下:
SELECT title FROM pgweb WHERE to_tsvector('english', body) @@ to_tsquery('english', 'friend');
這也會找到相關的單字,例如 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
表示法不會明確儲存。
如果您在文件中發現任何不正確、與您使用特定功能的經驗不符或需要進一步澄清的地方,請使用此表單回報文件問題。