将前缀匹配添加到pg_search

时间:2013-04-21 09:57:00

标签: ruby-on-rails postgresql railscasts pg-search

我正在关注this Railscasts剧集。

如果我搜索“Kerber”,它确实会返回正确的文章。 但是,如果我搜索“Ke”,它不会返回相同的文章。

有办法解决这个问题吗?

class Item < ActiveRecord::Base
  include PgSearch
  pg_search_scope :search, against: [:description, :about, :link, :twitterhandle, :builtby],
  using: {tsearch: {dictionary: "english"}}

  def self.text_search(query)
    if query.present?
      search(query)
    else
      scoped
    end
  end

2 个答案:

答案 0 :(得分:7)

我是pg_search的作者和维护者。

您可以将prefix: true添加到:tsearch搜索功能的配置中,让pg_search自动将:*添加到您的查询结尾。

https://github.com/Casecommons/pg_search#prefix-postgresql-84-and-newer-only

class Item < ActiveRecord::Base
  include PgSearch
  pg_search_scope :search, against: [:description, :about, :link, :twitterhandle, :builtby],
  using: {tsearch: {prefix: true, dictionary: "english"}}

  def self.text_search(query)
    if query.present?
      search(query)
    else
      scoped
    end
  end
end

答案 1 :(得分:3)

这个结果对我有意义。 KeKerber是不同的字词,因此它们在全文搜索中不匹配。

全文搜索仅阻止 - 删除复数等 - 以便cats匹配cat。即使这并不完全聪明 - 像dice这样的非典型复数也没有得到处理。它也只适用于目标语言词典中识别的单词,因此即使KerberKe的复数形式,当语言设置为english时也不会阻止它。

参见tsquery和tsvectors:

regress=> SELECT to_tsvector('Kerber'), to_tsquery('Kerber'), to_tsvector('ke'), to_tsquery('ke');
 to_tsvector | to_tsquery | to_tsvector | to_tsquery 
-------------+------------+-------------+------------
 'kerber':1  | 'kerber'   | 'ke':1      | 'ke'
(1 row)

和比赛:

regress=> SELECT to_tsvector('Kerber') @@ to_tsquery('Kerber'), to_tsvector('kerber') @@ to_tsquery('ke');
 ?column? | ?column? 
----------+----------
 t        | f                                                                                                                                                                  
(1 row)        

我怀疑你想要tsearch prefix match。这用:*通配符表示:

regress=> SELECT to_tsvector('kerber') @@ to_tsquery('ke:*');
 ?column? 
----------
 t
(1 row)

适用于前缀匹配。它可以对搜索效率产生影响,但我不认为它是一个主要的搜索效率。