LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

解放你的搜索功能!深入淺出PostgreSQL全文搜索(FTS)實(shí)戰(zhàn)指南

maoxiaoming
2025年8月23日 17:21 本文熱度 162

引言:為什么不用LIKE?

當(dāng)我們需要在文章、帖子或產(chǎn)品描述中搜索關(guān)鍵詞時(shí),第一個(gè)蹦進(jìn)腦海的可能是SQL的LIKEILIKE操作符:

sql
SELECT * FROM posts WHERE body LIKE '%postgres%';

這種方式簡(jiǎn)單但問(wèn)題很多:

  1. 性能極差%postgres%這種前導(dǎo)通配符無(wú)法利用索引,會(huì)導(dǎo)致全表掃描

  2. 不夠智能:它只能進(jìn)行嚴(yán)格的字符匹配。搜索"run",不會(huì)找到"running""ran"

  3. 沒(méi)有相關(guān)性排序:它只能告訴你“有”或“沒(méi)有”,無(wú)法告訴你哪條結(jié)果更相關(guān)。

而PostgreSQL內(nèi)置的全文搜索(Full-Text Search, FTS) 就是為了解決這些問(wèn)題而生的。


一、核心概念:文檔、向量與查詢(xún)

PostgreSQL的FTS將搜索過(guò)程抽象為三步:

  1. 文檔(Document):待搜索的文本單元。可以是一篇文章、一條評(píng)論,或者由多個(gè)字段組合而成的文本(如 title || ' ' || body)。

  2. 向量(tsvector):對(duì)文檔進(jìn)行處理后的產(chǎn)物。它:

    • 解析和分詞:將文本拆分成一個(gè)個(gè)獨(dú)立的 token(詞位)。

    • 標(biāo)準(zhǔn)化:轉(zhuǎn)換為小寫(xiě)。

    • 去除停用詞:移除atheis等常見(jiàn)但無(wú)搜索意義的詞。

    • 提取詞干:將單詞變?yōu)槠湓~根形式(如 running -> run)。

    • 最終存儲(chǔ)的是(詞位, 位置)形式的列表。

  3. 查詢(xún)(tsquery):代表用戶(hù)要搜索的內(nèi)容。它也可以進(jìn)行詞干提取,并支持邏輯操作符(& 與, | 或, ! 非)。

搜索的本質(zhì),就是判斷 @@ 操作符兩邊的 tsvector 和 tsquery 是否匹配。


二、逐行詳解示例SQL

拆解以下SQL語(yǔ)句:

sql
SELECT title, body
FROM posts
WHERE to_tsvector('english', body) @@ to_tsquery('english', 'postgres & optimization');
  • to_tsvector('english', body)

    • 功能:生成一個(gè) tsvector

    • 參數(shù)1:'english':這是一個(gè)文本搜索配置(Text Search Configuration)。它決定了使用哪種語(yǔ)言的規(guī)則進(jìn)行分詞、停用詞處理和詞干提取。PostgreSQL支持多種語(yǔ)言(如simpleenglishspanishrussian等)。配置的選擇直接影響搜索結(jié)果。

    • 參數(shù)2:body:需要被處理的文本字段。

    • 結(jié)果示例:假設(shè)body字段內(nèi)容是 "PostgreSQL provides powerful optimization tools.",經(jīng)過(guò)處理后會(huì)變成: 'power':5 'optim':6 'postgresql':1 'provid':2 'tool':7。可以看到,provides變成了provid(詞干提取),the被移除(停用詞)。

  • to_tsquery('english', 'postgres & optimization')

    • 功能:生成一個(gè) tsquery

    • 參數(shù)1:'english':同樣需要指定配置,確保查詢(xún)?cè)~和處理文檔時(shí)使用相同的規(guī)則(例如,optimization也會(huì)被提取詞干為optim)。

    • 參數(shù)2:'postgres & optimization':查詢(xún)字符串。&表示同時(shí)包含這兩個(gè)詞。

    • 結(jié)果:一個(gè)代表包含詞干 'postgres' 且 包含詞干 'optim'的查詢(xún)對(duì)象。

  • @@ 操作符

    • 功能:布爾匹配操作符。如果左邊生成的 tsvector 匹配右邊生成的 tsquery,則返回true,該行記錄就會(huì)被選中。


三、超越基礎(chǔ):排名與高亮

僅僅找到匹配的文檔還不夠,我們通常需要最好的結(jié)果排在前面。

  1. 相關(guān)性排名(Ranking): 使用ts_rank函數(shù)。

    sql
    SELECT title, body,
           ts_rank(to_tsvector('english', body), 
                   to_tsquery('english', 'postgres & optimization')) AS rank
    FROM posts
    WHERE to_tsvector('english', body) @@ to_tsquery('english', 'postgres & optimization')
    ORDER BY rank DESC;

    ts_rank會(huì)根據(jù)詞位出現(xiàn)的頻率、位置等因素計(jì)算一個(gè)相關(guān)性分?jǐn)?shù),然后通過(guò)ORDER BY rank DESC將最相關(guān)的結(jié)果排在頂部。

  2. 結(jié)果高亮(Highlighting): 使用ts_headline函數(shù)。

    sql
    SELECT title,
           ts_headline('english', body, 
                       to_tsquery('english', 'postgres & optimization')) AS headline
    FROM posts
    WHERE ...;

    ts_headline會(huì)在結(jié)果中環(huán)繞匹配到的詞加上諸如<b>...</b>這樣的HTML標(biāo)簽,讓用戶(hù)在上下文中一眼就看到為什么這條結(jié)果被匹配上了,體驗(yàn)堪比專(zhuān)業(yè)搜索引擎。


四、性能優(yōu)化:GiST/GIN 索引

WHERE子句中使用函數(shù)調(diào)用(如to_tsvector(...))通常會(huì)導(dǎo)致無(wú)法使用索引。為了讓全文搜索飛起來(lái),必須創(chuàng)建專(zhuān)門(mén)的索引

首選GIN索引,它專(zhuān)為這種“多值列”(一個(gè)tsvector里包含很多個(gè)詞位)的查詢(xún)而優(yōu)化。

sql
-- 1. 創(chuàng)建一個(gè)生成的tsvector列(推薦,易于管理和索引)
ALTER TABLE posts
ADD COLUMN body_tsvector tsvector
GENERATED ALWAYS AS (to_tsvector('english', COALESCE(body, ''))) STORED;
-- 2. 在生成的列上創(chuàng)建GIN索引
CREATE INDEX idx_posts_body_fts ON posts USING GIN(body_tsvector);
-- 3. 查詢(xún)語(yǔ)句變得更簡(jiǎn)單高效
SELECT title, body
FROM posts
WHERE body_tsvector @@ to_tsquery('english', 'postgres & optimization');

五、與Elasticsearch的比較

特性PostgreSQL FTSElasticsearch
部署復(fù)雜度零成本,內(nèi)置,無(wú)需額外部署需要單獨(dú)部署和維護(hù)另一個(gè)分布式系統(tǒng)
數(shù)據(jù)一致性強(qiáng)一致,搜索和事務(wù)在同一數(shù)據(jù)庫(kù),無(wú)延遲最終一致,數(shù)據(jù)同步有延遲(取決于刷新間隔)
功能豐富度支持基礎(chǔ)到中級(jí)的需求(分詞、排名、高亮)極其豐富,專(zhuān)業(yè)的分布式搜索引擎,支持聚合分析、同義詞、拼音搜索等
性能與擴(kuò)展性單機(jī)性能優(yōu)秀,可通過(guò)分片擴(kuò)展大規(guī)模分布式搜索和水平擴(kuò)展而生

結(jié)論:如何選擇?

  • 使用PostgreSQL FTS:如果你的搜索需求是應(yīng)用內(nèi)的、非核心的(如博客搜索、后臺(tái)管理搜索),并且你希望保持技術(shù)棧簡(jiǎn)單、保證數(shù)據(jù)一致性。

  • 使用Elasticsearch:如果你的業(yè)務(wù)核心是搜索(如電商平臺(tái)、新聞網(wǎng)站),需要處理海量數(shù)據(jù)、復(fù)雜的搜索邏輯和高吞吐量。

總結(jié)

PostgreSQL的全文搜索是一個(gè)被嚴(yán)重低估的“隱藏寶石”。它提供了一個(gè)在** simplicity(簡(jiǎn)單性)** 和 power(功能) 之間絕佳平衡的解決方案。對(duì)于許多不需要Elasticsearch這種“重武器”的應(yīng)用場(chǎng)景來(lái)說(shuō),它完全足夠且是更優(yōu)雅的選擇。

通過(guò)本文的介紹,希望你能在你的下一個(gè)項(xiàng)目中輕松上手這項(xiàng)強(qiáng)大功能!

討論點(diǎn):

  1. 大家在項(xiàng)目中是用PG的全文搜索還是ES?為什么做出這個(gè)選擇?

  2. 在處理中文全文搜索時(shí),有什么好的配置或分詞方案推薦嗎?(這是一個(gè)常見(jiàn)痛點(diǎn),可以引出zhparser等擴(kuò)展的討論)

?

該文章在 2025/8/23 17:22:12 編輯過(guò)
關(guān)鍵字查詢(xún)
相關(guān)文章
正在查詢(xún)...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專(zhuān)業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車(chē)隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類(lèi)企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷(xiāo)售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶(hù)的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
在线观看免费的AV片 | 香蕉精品偷在线观看 | 一本一本大道香蕉久在线精品 | 欧美一级成在线人 | 亚卅日韩久久影视观看 | 在线播放一区二区不三区 |