Преобразование введенного пользователем поискового запроса в предложение where для использования в полнотекстовом поиске SQL Server. - PullRequest
12 голосов
/ 03 февраля 2009

Каков наилучший способ преобразования поисковых терминов, введенных пользователем, в запрос, который можно использовать в предложении 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 из токенов.

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

Ответы [ 6 ]

8 голосов
/ 23 мая 2015

Как реализовать принятый ответ, используя .Net / C # / Entity Framework ...

  1. Установите Irony с помощью nuget.

  2. Добавить образец класса из: http://irony.codeplex.com/SourceControl/latest#Irony.Samples/FullTextSearchQueryConverter/SearchGrammar.cs

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

    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);
    
  4. Возможно, напишите хранимую процедуру следующим образом:

    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
    
  5. Запустить запрос.

    var fishes = db.SearchLivingFish(query);
    
5 голосов
/ 03 февраля 2009

Это может быть не совсем то, что вы ищете, но это может предложить вам некоторые дополнительные идеи.

http://www.sqlservercentral.com/articles/Full-Text+Search+(2008)/64248/

1 голос
/ 11 августа 2015

В дополнение к ответу @ franzo, приведенному выше, вы, вероятно, также хотите изменить поведение стоп-слов по умолчанию в SQL. В противном случае запросы, содержащие однозначные числа (или другие стоп-слова), не вернут никаких результатов.

Либо отключите стоп-слова, создайте собственный список стоп-слов и / или установите шумовые слова для преобразования, как описано в SQL 2008: отключить стоп-слова для запроса полнотекстового поиска

Чтобы просмотреть системный список (английских) стоп-слов sql, выполните:

select * from sys.fulltext_system_stopwords where language_id = 1033
0 голосов
/ 30 октября 2009

Комбинация GoldParser и Calitha должна уладить вас здесь.

Эта статья: http://www.15seconds.com/issue/070719.htm также имеет класс googleToSql, который выполняет некоторые переводы для вас.

0 голосов
/ 03 февраля 2009

Самый простой способ сделать это - использовать динамический SQL (я знаю, вставьте сюда проблемы безопасности) и разбить фразу на правильно отформатированную строку.

Вы можете использовать функцию, чтобы разбить фразу на табличную переменную, которую можно использовать для создания новой строки.

0 голосов
/ 03 февраля 2009

Я понимаю, что это немного в стороне от вашего первоначального вопроса, но рассматривали ли вы возможность отказаться от полнотекстовых индексов SQL и использовать что-то вроде Lucene / Solr вместо?

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