Ответ 1
Это может быть не совсем то, что вы ищете, но оно может предложить вам дополнительные идеи.
http://www.sqlservercentral.com/articles/Full-Text+Search+(2008)/64248/
Какой лучший способ конвертировать поисковые запросы, введенные пользователем, в запрос, который может использоваться в предложении where для полнотекстового поиска для запроса таблицы и получения соответствующих результатов? Например, следующий запрос, введенный пользователем:
+"e-mail" +attachment -"word document" -"e-learning"
Должен перевести что-то вроде:
SELECT * FROM MyTable WHERE (CONTAINS(*, '"e-mail"')) AND (CONTAINS(*, '"attachment"')) AND (NOT CONTAINS(*, '"word document"')) AND (NOT CONTAINS(*, '"e-learning"'))
В данный момент я использую класс парсера запросов, который анализирует запрос, введенный пользователями в токены, используя регулярное выражение, а затем создает предложение where из токенов.
Однако, учитывая, что это, вероятно, общее требование для многих систем, использующих полнотекстовый поиск, мне любопытно, как другие разработчики подошли к этой проблеме, и есть ли лучший способ сделать что-то.
Это может быть не совсем то, что вы ищете, но оно может предложить вам дополнительные идеи.
http://www.sqlservercentral.com/articles/Full-Text+Search+(2008)/64248/
Как реализовать принятый ответ с использованием .Net/С#/Entity Framework...
Установите Ирония, используя nuget.
Добавить класс образца из: http://irony.codeplex.com/SourceControl/latest#Irony.Samples/FullTextSearchQueryConverter/SearchGrammar.cs
Введите такой код, чтобы преобразовать введенную пользователем строку в запрос.
var grammar = new Irony.Samples.FullTextSearch.SearchGrammar();
var parser = new Irony.Parsing.Parser(grammar);
var parseTree = parser.Parse(userEnteredSearchString);
string query = Irony.Samples.FullTextSearch.SearchGrammar.ConvertQuery(parseTree.Root);
Возможно, напишите хранимую процедуру следующим образом:
create procedure [dbo].[SearchLivingFish]
@Query nvarchar(2000)
as
select *
from Fish
inner join containstable(Fish, *, @Query, 100) as ft
on ft.[Key] = FishId
where IsLiving = 1
order by rank desc
Запустите запрос.
var fishes = db.SearchLivingFish(query);
В дополнение к ответу @franzo выше вы, вероятно, также захотите изменить поведение стоп-слова по умолчанию в SQL. В противном случае запросы, содержащие однозначные числа (или другие слова остановки), не возвратят никаких результатов.
Либо отключите стоп-слова, создайте свой собственный список стоп-слов и/или установите шумовые слова, которые будут преобразованы, как объяснено в SQL 2008: Отключить стоп-слова для запроса полного текста
Чтобы просмотреть системный список (английских) слов sql stop, запустите:
select * from sys.fulltext_system_stopwords where language_id = 1033
Я понимаю это немного побочный шаг от вашего первоначального вопроса, но вы подумали о том, чтобы отойти от полнотекстовых индексов SQL и использовать что-то вроде Lucene/Solr вместо этого?
Самый простой способ сделать это - использовать динамический SQL (я знаю, вставьте проблемы безопасности здесь) и сломал фразу в правильно отформатированную строку.
Вы можете использовать функцию, чтобы разбить фразу на переменную таблицы, которую вы можете использовать для создания новой строки.
Комбинация GoldParser и Calitha должна отсортировать вас здесь.
В этой статье: http://www.15seconds.com/issue/070719.htm имеет класс googleToSql, который выполняет некоторые переводы для вас.