Полнотекстовый поиск SQL Server

В настоящее время я работаю над приложением, в котором у нас есть база данных SQL-Server, и мне нужно заставить работать полнотекстовый поиск, который позволяет нам искать имена людей.

В настоящее время пользователь может ввести в поле имени, которое ищет 3 разных столбца varchar. Имя, Фамилия, Отчество

Скажем, у меня есть 3 строки со следующей информацией.

1 - Филипп - Джей - Фрай

2 - Эми - NULL - Вонг

3 - Лео - NULL - Вонг

Если пользователь вводит имя, такое как «Фрай», он вернет строку 1. Однако, если они введут Филиппа Фрая, или Фра, или Фила, они ничего не получат ... и я не понимаю, почему он это делает. Если они ищут Вонга, они получают строки 2 и 3, если они ищут Эми Вонг, они снова ничего не получают.

В настоящее время запрос использует CONTAINSTABLE, но я переключил его на FREETEXTTABLE, CONTAINS и FREETEXT без каких-либо заметных различий в результатах. Табличные методы предпочтительнее, потому что они возвращают те же результаты, но с ранжированием.

Вот запрос.

....
@Name nvarchar(100),
....
--""s added to prevent crash if searching on more then one word.
DECLARE @SearchString varchar(100)
SET @SearchString = '"'[email protected]+'"'
SELECT Per.Lastname, Per.Firstname, Per.MiddleName
FROM Person as Per
INNER JOIN CONTAINSTABLE(Person, (LastName, Firstname, MiddleName), @SearchString) 
AS KEYTBL
ON Per.Person_ID = KEYTBL.[KEY]
WHERE KEY_TBL.RANK > 2
ORDER BY KEYTBL.RANK DESC;  
....

Любые идеи...? Почему этот полнотекстовый поиск работает некорректно?

Ответов (5)

Решение

Спасибо за ответы, ребята, я наконец смог заставить его работать. С частью ответов как Бири, так и Кибби. Мне нужно было добавить * к строке и разбить ее на пробелы, чтобы работать. Итак, в конце концов я получил

....
@Name nvarchar(100),
....
--""s added to prevent crash if searching on more then one word.
DECLARE @SearchString varchar(100)

--Added this line
SET @SearchString = REPLACE(@Name, ' ', '*" OR "*')
SET @SearchString = '"*'[email protected]+'*"'

SELECT Per.Lastname, Per.Firstname, Per.MiddleName
FROM Person as Per
INNER JOIN CONTAINSTABLE(Person, (LastName, Firstname, MiddleName), @SearchString) 
AS KEYTBL
ON Per.Person_ID = KEYTBL.[KEY]
WHERE KEY_TBL.RANK > 2
ORDER BY KEYTBL.RANK DESC;  
....

Есть еще поля, по которым выполняется поиск. Я просто упростил его для вопроса, извините за это, я не думал, что это повлияет на ответ. На самом деле он выполняет поиск в столбце, в котором есть псевдонимы в формате CSV, а также столбец примечаний.

Спасибо за помощь.

FreeTextTable должен работать.

INNER JOIN FREETEXTTABLE(Person, (LastName, Firstname, MiddleName), @SearchString) 

@SearchString должна содержать такие значения, как «Phillip Fry» (одна длинная строка, содержащая все строки поиска, разделенные пробелами).

Если вы хотите найти Fr или Phil, вы должны использовать звездочку: Phil * и Fr *

«Фил» ищет именно слово «Фил». "Фил *" ищет все слова, начинающиеся с "Фил".

Если вы просто ищете людей по именам, возможно, в ваших интересах даже не использовать полнотекстовый индекс. Полнотекстовый индекс имеет смысл, когда у вас есть большие текстовые поля, но если вы в основном имеете дело с одним словом в поле, я не уверен, сколько дополнительных вы получите от полнотекстовых индексов. Ожидание переиндексации полнотекстового индекса перед поиском новых записей может быть одной из многих проблем.

Вы можете просто задать следующий запрос. Разделите строку поиска на пробелы и создайте список условий поиска.

Выберите имя, отчество, фамилию. 
От человека 
КУДА 
Имя типа @ searchterm1 + '%'
или MiddleName, например @ searchterm1 + '%'
или Фамилия, например @ searchterm1 + '%'
или Имя, например @ searchterm2 + '%'
так далее....

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

Другими словами, создайте представление о ваших данных, которое превращает все разделенные поля, такие как firstname lastname, в составные поля, то есть full_name

Затем выполните поиск по представлению. Это, вероятно, упростит поисковый запрос.

Возможно, вы захотите проверить Lucene.net в качестве альтернативы полному тексту.