SQL Полнотекстовый поиск на сервере не дает ожидаемых результатов - PullRequest
0 голосов
/ 04 февраля 2020

Я установил полнотекстовый поиск для SQL Сервера, создал каталог и индекс. Я уверен, что в базе данных есть правильные записи, но функции FTS не возвращают никакого результата.

Например:

select * from tablename where contains(title, 'baycan');
select * from tablename where contains(title, '"*baycan*"')

Это изображение каталога и индекса:

enter image description here

1 Ответ

3 голосов
/ 04 февраля 2020

Похоже, вы неправильно понимаете CONTAINS и LIKE, они не эквивалентные операторы. Из СОДЕРЖИТ (Transact- SQL) :

СОДЕРЖИТ может искать:

  • Слово или словосочетание.
  • Префикс слова или фразы.
  • Слово рядом с другим словом.
  • Слово, порождённое из другого слова (например, слова «диск» - это флективная основа приводов, водил, водил и водил).

Слово, которое является синонимом другого слова, использующего тезаурус (например, слово «металл» может иметь такие синонимы, как как "алюминий" и "сталь").

Подчеркну мое собственное.

CONTAINS не поддерживает символ подстановки, только конечный. В результате (как я уже сказал в своем комментарии) для столбца (title) со значением 'abaycant' выражение WHERE title LIKE '%baycan%' вернет TRUE, однако CONTAINS(title,'baycan') не будет.

Если у вас есть значение 'baycant', тогда LIKE 'baycan%' и CONTAINS(title,'baycan*')LIKE '%baycan%') все вернут TRUE; первый 2 также будет SARGable (тот, что в скобках не будет).

Если бы значение было 'best baycant', то и CONTAINS(title,'baycan*'), и LIKE '%baycan%' вернули бы ИСТИНА, но только первое будет SARGable.

Это также дополнительно поддерживается позже в разделе аргументов в отношении параметра фраза (второй параметр) при использовании его в качестве префикса (в аргументах для параметра отсутствует опция суффикс или «в середине»):

<prefix_term>

Указывает совпадение слов или фраз, начинающихся с указанного текста. Заключите префиксный термин в двойные кавычки ("") и добавьте звездочку (*) перед конечной кавычкой, чтобы весь текст начинался с простого термина, указанного перед звездочкой. Пункт должен быть указан следующим образом: CONTAINS (column, '"text*"'). Звездочка соответствует нулю, одному или нескольким символам (из root слова или слов в слове или фразе). Если текст и звездочка не разделены двойными кавычками, поэтому предикат читает CONTAINS (column, 'text*'), полнотекстовый поиск рассматривает звездочку как символ и ищет точные совпадения с текстом *. Полнотекстовый движок не будет находить слова со звездочкой (*), поскольку средства разбиения по словам обычно игнорируют такие символы.

Когда <prefix_term> является фразой, каждое слово, содержащееся в фразе считается отдельным префиксом. Поэтому запрос с указанием префиксного термина «local wine *» сопоставляет любые строки с текстом «local wineery», «local wined and dined» и т. Д.

FREETEXT будет не меняй это. FREETEXT (Transact- SQL) :

Когда используется FREETEXT, механизм полнотекстовых запросов внутренне выполняет следующие действия над строкой freetext_string, присваивая каждому члену вес, и затем находит совпадения:

  • Разделяет строку на отдельные слова на основе границ слов (разбиение по словам).
  • Генерирует инфлективные формы слов ( stemming).
  • Идентифицирует список расширений или замен для терминов, основанных на совпадениях в тезаурусе.

Опять выделю мое.

Значение типа 'abaycant' не имеет границ слов, поэтому FREETEXT(title, 'baycan') не будет работать. Если вам нужен начальный подстановочный знак, из-за необходимости поиска в пределах слова вы не можете использовать полнотекстовый поиск, поскольку FTS индексирует слова, а не символы.

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