2016-09-01 103 views
0

我遇到的問題搜索我的數據庫中包含停止詞的遊戲名稱。我只尋找一般的精確匹配,我希望儘可能少的「模糊」命中我所有的搜索,最佳爲零。PostgreSQL全文搜索問題(to_tsquery)

E.g. content that produced false positives directly, contains sentences like; "the war in Afghanistan" + reference to "win*" another place; or "Lifeseed to win the war"; or "win the war that is taking over the galaxy" and so on.

這當然不工作,並給了一個錯誤:

SELECT id, title, content FROM my_table 
WHERE [email protected]@ to_tsquery('win that war'); 

,因爲它解決了我的一些其他搜索(PostgreSQL的9.6)我曾希望「phraseto_tsquery」 woudl工作,但由於在這其中也並沒有停止字:

SELECT id, title, content FROM my_table 
WHERE [email protected]@ phraseto_tsquery('win that war'); 

我用領帶戰鬥機的事情也試過,< 1> | < - >但通常它得到了誤報:

SELECT id, title, content FROM my_table 
WHERE [email protected]@ to_tsquery('win <-> that <-> war'); 

是否有任何黑客我可以在這裏做只得到其匹配的期望的結果返回的是一個短語匹配?我在想,也許我可以把它當作停止詞,不知道我是怎麼做到的,不知道這個解決方案有多好,可能也是爲了尋找「魔獸世界」和類似的標題而停止用詞(而且我一般只需要精確匹配)。

想法?

回答

0

要刪除部分或全部停用詞,請在PostgreSQL軟件目錄的share/tsearch_data子目錄中創建縮減的或空的停用詞文件。然後你就可以創建一個新的雪球文本檢索辭典與

CREATE TEXT SEARCH DICTIONARY newdict (
    TEMPLATE = pg_catalog.snowball, 
    language = '...', 
    stopwords = '...' 
); 

使用新的禁用詞文件,並創建一個基於一個新的文本搜索配置。這當然會使你的索引變大。

從你引用的例子,我寧願選擇不同的方法,並使用全文搜索,以便能夠使用索引來減少你的候選人,並進一步與第二個條件是這樣進行篩選:

SELECT id, title, content FROM my_table 
WHERE tsvector_combined @@ to_tsquery('win that war') 
    AND (title LIKE '%win that war%' OR content LIKE '%win that war%'); 
+0

我會試試這個,我首先關心的是你的首選方案可能是性能。相關數據庫將包含數百萬條文章,這是否會改變您的推薦解決方案? – user6776585

+0

不需要。帶有附加的'WHERE'子句的查詢不應該太昂貴,因爲PostgreSQL將首先應用索引條件,並使用'LIKE'過濾器來處理結果,希望它不會太大。當然,如果全文搜索返回了很多結果,情況會有所不同,但是這兩種方法都有問題。 –