RAILS3: поиск, игнорирующий диакритические знаки? - PullRequest
0 голосов
/ 17 октября 2011

У меня есть приложение Rails 3, которое содержит объекты Article. У них есть атрибут заголовка. Перед добавлением новой статьи люди должны выполнить поиск, чтобы узнать, существует ли уже статья с названием.

Сегодня кто-то сообщил о дублировании статьи. Оказывается, кто бы ни добавил его, он сначала искал его, но в заголовке было умлаут над «о». Они искали без умлаута, используя обычный символ «о», не нашли его и добавили дубликат.

Я делаю простой поиск атрибута title с областью действия, как показано ниже:

scope :search, lambda { |term| where('title like ?', "%#{term}%") }

Мне интересно, есть ли простой способ "игнорировать" диакритические знаки, чтобы человек мог напечатать "o" и все же найти статью, если у o есть умлаут, и то же самое для других диакритических знаков.

Я подумал о создании атрибута search_title и его заполнении при обновлении, заменяя диакритические знаки их простыми эквивалентами, но у них есть свои проблемы, в том числе, что если кто-то затем использует диакритический знак.

Я надеялся, что для этого может быть простое решение, но я не надеюсь на это. : -)

Ответы [ 2 ]

1 голос
/ 17 октября 2011

Да, стандартный способ справиться с этим - поддерживать теневое поле поиска. В дополнение к изменению всех данных на Ascii, рассмотрим:

  • Изменение всего на верхний регистр для устранения проблем с регистром
  • удаление всех символов, которые не являются цифрами, буквами или пробелами. (Удалить знаки препинания, табуляции и т. Д.)
  • удаление " стоп-слов ", таких как "is", "" a "и т. Д. Конечно, стоп-слова зависят от языка.

Альтернативной стратегией является вычисление и поиск на основе Soundex . (Или используйте пересмотренную версию Soundex). Есть библиотеки Ruby для Soundex или напишите свои собственные.

Soundex даст вам больше ложных срабатываний - вам нужно определить, хотите ли вы иметь больше ложных срабатываний или, возможно, пропустите совпадение (ложное отрицание), потому что один заголовок был "Чума", а другой - "Чума"

Вы также можете установить настоящую систему полнотекстового поиска, включив систему MySQL или через отдельную систему.

1 голос
/ 17 октября 2011

Я предлагаю создать поле search_title и сохранить там title.to_ascii_brutal (используйте этот плагин: https://github.com/tomash/ascii_tic)., а затем измените область поиска на:

scope :search, lambda { |term| where('search_title like ?', "%#{term.to_ascii_brutal}%") }
...