Полнотекстовый поиск - содержит подстановочный знак и одинарную кавычку

У меня есть таблица с полем имени с этим

Test O'neill 123

Если я использую

SELECT  *
    FROM    table F
    WHERE   CONTAINS ( F.*, '"Test O''neill 123"' )

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

SELECT  *
    FROM    table f
    WHERE   CONTAINS ( F.*, '"Test O''neill 123*"' )

почему это? Я использую синтаксический анализатор для моих условий поиска, и это добавляет подстановочный знак *

Я проверил несколько сайтов, чтобы избежать ' но я не нашел ничего, относящегося к этому..

Заранее спасибо

1 ответ

Решение

Проблема связана с комбинацией 1) использования нейтрального языка 2) плюс стоп-лист для вашего полнотекстового индекса 3) плюс неожиданное поведение при использовании подстановочного знака в поиске, включающем стоп-слова.

Нейтральный язык не охватывает все нюансы английского языка, поэтому в индексное время он учитывает O'neill быть 2 отдельными словами O а также neill, Тогда ваш стоп-лист считает O быть ключевым словом, так что это "слово" не добавляется в индекс, только neill является.

Во время поиска поисковая система обычно игнорирует стоп-слова в словосочетаниях. Например, поиск Contains(*, '"we x people"') будет соответствовать тексту ...we the people..., x а также the оба являются стоп-словами и, таким образом, автоматически "совпадают" друг с другом. (Я использую термин "сопоставление" свободно, потому что поисковая система не сопоставляет стоп-слова, а скорее знает, что people 1 слово от we.)

Таким образом, вы можете ожидать подстановочный поиск Contains(*, '"we the people*"') также найти его соответствие, за исключением того, что он не находит при использовании стоп-листа. Если бы не стоп-слово the в поисковой фразе, или если the не считаться стоп-словом, поиск будет работать нормально. Я действительно не могу объяснить это поведение, но я подозреваю, что это как-то связано с тем, как вычисляются положения слов. Я также подозреваю, что это не предполагаемое поведение.

Итак, вернемся к вашему делу, Contains(*, '"Test O''neill 123"') найдет совпадение, но поиск по шаблону Contains(*, '"Test O''neill 123*"') не. (Вы можете даже упростить поиск Contains(*, '"O''neill*"') и вы увидите, что он по-прежнему не находит соответствия.) Комбинация стоп-слов O с подстановочным знаком сталкивается с проблемой, которую я объяснил в предыдущем абзаце. В этом суть проблемы, изложенной в вашем вопросе.

Решения от самых эффективных до наименее эффективных, но, возможно, более практичных для вашего случая:

1) Измените язык вашего полнотекстового индекса на английский и переиндексируйте. Это приведет к O'neill будет рассматриваться как одно слово, и, таким образом, вы избежите странного подстановочного поведения, которое я объяснил. Вы можете изменить язык в свойствах полнотекстового индекса через SQL Server Management Studio или путем удаления и повторного создания индекса следующим образом:

ALTER FULLTEXT INDEX ON MyTable DROP (Column1) 
GO
ALTER FULLTEXT INDEX ON MyTable ADD (Column1 LANGUAGE [English])
-- repeat for each column in the index

2) Если вам нужно продолжать использовать нейтральный язык, рассмотрите возможность удаления O из вашего стоп-листа и переиндексации.

ALTER FULLTEXT STOPLIST MyStoplist DROP 'o' LANGUAGE 'Neutral';

3) Или не используйте стоп-лист, если он вам не нужен.

ALTER FULLTEXT INDEX ON MyTable SET STOPLIST = OFF

4) Если ни одно из приведенных выше решений не является практичным, рассмотрите возможность удаления стоп-слов из поисковой фразы или, по крайней мере, O' префикс в фамилиях.

Другие вопросы по тегам