Фон
У меня проблемы с поиском текста PostgreSQL с помощью to_tsvector. В основном он работает, за исключением того, что он не находит записи, когда в качестве строки запроса задано "Дон" .
Подробности
После нескольких попыток я написал запрос (Rails scope), чтобы найти пользователей по их имени. База данных имеет 2 столбца в пользовательской таблице first_name
и last_name
. Поскольку он используется в поиске с автозаполнением, я бы хотел, чтобы он возвращал результаты независимо от того, является ли его частью имени или фамилии ex:
User.with_name("ab") -> User(first_name: "Abc", last_name: "Def")
User.with_name("De") -> User(first_name: "Abc", last_name: "Def")
Я придумал что-то вроде этого:
scope :with_name, lambda { |name|
return scoped if name.blank?
name = name.to_s.strip
value = name.gsub(' ', '\\ ').gsub('(', '\(').gsub(')', '\)')
value << ":*" if name.present?
where(
"to_tsvector('english', first_name || ' ' || last_name) @@ to_tsquery('english', ?)",
value
)
}
У меня это хорошо работало в течение многих лет, за исключением прошлой недели, когда была жалоба на то, что определенный c пользователь не показывает никаких результатов при поиске «Дон». Я не могу найти никаких причин, почему "Дон" не включен. На самом деле есть 2 "Дона".
Я заметил, что появляются 3 буквенных имени. Также, если я сделаю «Дон Sh» с частью фамилии, пользователь появится в результатах.
Если вы хотите, посмотрите на сгенерированный SQL:
SELECT "users".* FROM "users" WHERE (to_tsvector('english', first_name || ' ' || last_name) @@ to_tsquery('english', 'Don:*'))
Справка
- Есть ли лучший способ реализовать поиск по полю автозаполнения?
- Почему это происходит и можно ли это исправить?