Преобразование введенного пользователем поискового запроса в предложение where для использования в полнотекстовом поиске SQL Server

StackOverflow https://stackoverflow.com/questions/506034

Вопрос

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

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

  2. Добавьте образец класса из:http://irony.codeplex.com/SourceControl/latest#Irony .Образцы/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);
    

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

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

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

select * from sys.fulltext_system_stopwords where language_id = 1033

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

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

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

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

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

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