如何在 PostgreSQL 全文搜尋中搜尋連字元?
我必須搜尋諸如“早安”、“晚安”等連字元的單詞。
我的查詢是:
select id, ts_headline(content, to_tsquery('english','good-morning'), 'HighlightAll=true MaxFragments=100 FragmentDelimiter=$') from table where ts_content @@ to_tsquery('english','good-morning');
執行此查詢時,我還分別得到*“好”和“早上”的*結果。但我想要完全匹配的單詞和片段。
(因為
ts_content
我使用相同的預設配置english
來創建tsvector
。)如何在 PostgreSQL 全文搜尋中搜尋此類連字元?
這裡的關鍵詞是片語搜尋**,它是在Postgres 9.6**中引入的。
使用
tsquery
FOLLOWED BY 運算符**<->
**或相關<N>
運算符之一。或者更好的是,使用該函式phraseto_tsquery()
生成您的tsquery
.引用手冊,它…
生成
tsquery
搜尋片語,忽略標點符號
phraseto_tsquery
行為很像plainto_tsquery
,除了它<->
在倖存的單詞之間插入 (FOLLOWED BY) 運算符而不是&
(AND) 運算符。此外,停用詞不是簡單地丟棄,而是通過插入<N>
運算符而不是<->
運算符來解釋。此函式在搜尋精確的詞位序列時很有用,因為 FOLLOWED BY 運算符檢查詞位順序而不僅僅是所有詞位的存在。您的查詢將像這樣工作:
select id , ts_headline(content, phraseto_tsquery('english', 'good-morning') , 'HighlightAll=true MaxFragments=100 FragmentDelimiter=$') from tbl where ts_content @@ phraseto_tsquery('english','good-morning');
phraseto_tsquery('english', 'good-morning')
生成這個tsquery
:'good-morn' <-> 'good' <-> 'morn'
由於“早安”被標識為
asciihword
(帶連字元的 ASCII 詞),因此在組件之前添加了詞幹完整的詞。手冊:解析器可以從同一段文本生成重疊標記。例如,一個連字元的單詞將被報告為整個單詞和每個組件:(後面是一個範例)
to_tsvector()
基本上在另一端做同樣的事情,所以一切都匹配。這允許帶有連字元的細粒度選項。以上僅找到帶有連字元(或相同的變體)的“早安”。要查找所有帶有“good”後跟“morn”的字元串(或衍生相同的變體),請使用phraseto_tsquery('english','good morning')
生成此 tsquery:'good' <-> 'morn'
OTOH,您可以通過添加另一個過濾器來強制執行完全匹配,例如:
... AND content ~* 'good-morning' -- case insensitive regexp match
或者:
... AND content ILIKE '%good-morning%'
對人眼來說似乎有點多餘,但通過這種方式,您可以獲得快速的全文索引支持和 完全匹配。
後者大部分是等價的,但不同(更少)字元在
LIKE
模式中具有特殊含義,可能需要轉義。有關的:展示運算符的範例
<N>
:
phraseto_tsquery('english', 'Juliet and the Licks')
生成這個tsquery
:'juliet' <3> 'lick'
<3>
這意味著lick
必須是 . 之後的第三個詞位juliet
。