Вопрос

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

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

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

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

2 – Эми – НОЛЬ – Вонг

3 – Лев – НОЛЬ – Вонг

Если пользователь вводит имя, например «Фрай», он вернет строку 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 = '"'+@Name+'"'
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;  
....

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

Это было полезно?

Решение 3

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

....
@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 = '"*'+@SearchString+'*"'

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 должен содержать такие значения, как «Филлип Фрай» (одна длинная строка, содержащая все строки поиска, разделенные пробелами).

Если вы хотите найти отца или Фила, вам следует использовать звездочку:Фил* и Фр*

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

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

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

Select FirstName,MiddleName,LastName 
From person 
WHERE 
Firstname like @searchterm1 + '%'
or MiddleName like @searchterm1 + '%'
or LastName like @searchterm1 + '%'
or Firstname like @searchterm2 + '%'
etc....

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

Другими словами, создайте представление ваших данных, которое преобразует все разделенные поля, такие как имя, фамилия, в объединенные поля, т.е.полное имя

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top