Добавление совпадения префикса в pg_search

Я слежу за этим эпизодом Railscasts.

Если я ищу «Кербер», он возвращает правильную статью. Но если я ищу «Ке», он не возвращает ту же статью.

Есть способ исправить это?

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

person Sullivan    schedule 21.04.2013    source источник


Ответы (2)


Я автор и сопровождающий 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
person Grant Hutchins    schedule 23.04.2013
comment
Handy, спасибо, что следите за этим. Так много postgresql вопросов о стольких различных наборах инструментов, языках и т. д. ... не могут знать подробности о них всех. - person Craig Ringer; 24.04.2013

Этот результат имеет смысл для меня. 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)

Это работает только для сопоставления префиксов. Это может повлиять на эффективность поиска, но я не думаю, что это серьезно.

person Craig Ringer    schedule 21.04.2013
comment
Это именно то, что я имел в виду. Добавление Prefix Match в модель Items решило мою проблему. Большое спасибо! - person Sullivan; 22.04.2013