3

我正在关注这个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
4

2 回答 2

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
于 2013-04-23T02:45:38.893 回答
3

这个结果对我来说很有意义。Ke并且Kerber是不同的词,因此它们在全文搜索中不匹配。

全文搜索只进行词干提取- 删除复数等 - 以便cats匹配cat. 即使这也不是很聪明 -dice不处理非典型复数。它也仅适用于目标语言词典中识别的单词,因此即使Kerber是它的复数Ke也不会在语言设置为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 前缀匹配。这用:*通配符表示:

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

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

于 2013-04-21T11:43:00.923 回答