使用PostgreSQL在多列中进行全文搜索

时间:2013-06-28 01:33:56

标签: ruby-on-rails postgresql full-text-search

我刚开始使用postgreSQL进行模糊文本匹配。我有两列:job_titlecompany_name

典型的全文搜索会连接job_titlecompany_name,然后根据单个排名返回搜索文本结果。

但是,在我的情况下,同等对待两列中的文本匹配可能会有问题。例如,Search EngineerGoogle Co.的{​​{1}}不能与Google Search Engineer Co.的{​​{1}}平分

我知道我可以为每列分配不同的权重。但是,我没有理由比其他人更重要。

如何将我的关键字分别与每个列匹配,并在每个关键字上返回一些“匹配得分”?

类似的东西:

Jobs.where("(to_tsvector('english', position) @@ plainto_tsquery(:q)) AND 

(to_tsvector('english',company) @@ plainto_tsquery(:q))", q: "Search Engineer", q: "Google")

1 个答案:

答案 0 :(得分:1)

正如您所指出的,您可以连接tsvectors:

# select to_tsvector('job description') ||
         to_tsvector('company as keyword') ||
         to_tsvector('job description as body') as vector;
                          vector                           
-----------------------------------------------------------
 'bodi':9 'compani':3 'descript':2,7 'job':1,6 'keyword':5
(1 row)

你也可以为它们分配权重:

# select (setweight(to_tsvector('job description'), 'A') ||
         setweight(to_tsvector('company as keyword'), 'B') ||
         setweight(to_tsvector('job description as body'), 'D')) as vector;
                            vector                             
---------------------------------------------------------------
 'bodi':9 'compani':3B 'descript':2A,7 'job':1A,6 'keyword':5B
(1 row)

你也可以玩ts_rank_cd()。特别是,您可以更改分数的标准化方式。

http://www.postgresql.org/docs/current/static/textsearch-controls.html

在您的情况下,您似乎想要组合两个单独的查询。一个丑陋但可能足够的解决方案可能如下所示:

select sum(rank) as rank, ...
from (
   select ...
   union all
   select ...
   ) as sub
group by ...
order by sum(rank) desc
limit 10

正如你所看到的,它不是很漂亮。它也是一个用于聚合潜在大量匹配行的大道。 Imho,你最好坚持使用内置的tsvector算法并根据需要调整权重。