PostgreSQL - Текстовый поиск с to_tsvector - Пропуск некоторых записей - PullRequest
0 голосов
/ 05 мая 2020

Фон

У меня проблемы с поиском текста 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:*'))

Справка

  1. Есть ли лучший способ реализовать поиск по полю автозаполнения?
  2. Почему это происходит и можно ли это исправить?

1 Ответ

1 голос
/ 07 мая 2020

Don - это стоп-слово на английском языке sh. Я предполагаю, что это потому, что это то, до чего разбирается don't; поскольку don сам по себе (противоположность doff) не является общим для слова сам по себе.

Вы можете переключиться с 'engli sh' на 'simple', поскольку 'simple' не делает Не реализую стоп-слова. Конечно, для этого потребуется изменить вашу программу и перестроить индекс.

В качестве альтернативы вы также можете просто удалить don из SHAREDIR/tsearch_data/english.stop, а затем перестроить индекс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...