2016-09-01 122 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'过滤器来处理结果,希望它不会太大。当然,如果全文搜索返回了很多结果,情况会有所不同,但是这两种方法都有问题。 –