Как: строка C # для поиска в полнотекстовом каталоге SQL? - PullRequest
1 голос
/ 09 июля 2010

У меня есть несколько поисковых запросов, таких как:

Джордж И НЕ Вашингтон ИЛИ Авраам

СОБАКА ИЛИ КОШКА И НЕ ВОЛК

для этих поисков я хотел бы получить результаты для Джорджа или Авраама, но не Вашингтона и т. Д.

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

Я предполагаю, что должен использовать Regex, но я очень незнаком с Regex в C #.

Я нашел эту статью: http://support.microsoft.com/kb/246800 что я думаю, это то, что мне нужно сделать, но я надеялся, что смогу помочь с реализацией.

Предполагается, что вы берете строку в качестве параметра и хотите вернуть строку:

string input = 'George Washington AND NOT Martha OR Dog';

private string interpretSearchQuery(input)
{
     // HALP!

        /* replace ' AND ' | ' AND NOT ' with
         * " AND "
         * " AND NOT "
         * 
         * replace ' OR ' | ' OR NOT ' with
         * " OR "
         * " OR NOT "
         * 
         * add " to beginning of string and " to end of string
         */

     return '"George Washington" AND NOT "Martha" OR "Dog"';
}

Ответы [ 3 ]

4 голосов
/ 09 июля 2010

Я бы проанализировал вашу строку, используя Постфиксная запись (или польская запись).

**Postfix algorithm**
The algorithm for evaluating any postfix expression is fairly straightforward:

While there are input tokens left    

  Read the next token from input.

  If the token is a value
    Push it onto the stack.

  Otherwise, the token is an operator (operator here includes both operators, and functions). 
   It is known a priori that the operator takes n arguments. 

   If there are fewer than n values on the stack 
     (Error) The user has not input sufficient values in the expression. 
   Else, Pop the top n values from the stack. 

   Evaluate the operator, with the values as arguments. 
   Push the returned results, if any, back onto the stack. 

If there is only one value in the stack 
  That value is the result of the calculation. 

If there are more values in the stack 
  (Error) The user input has too many values.

Итак, взяв вашу входную строку:

'Джордж Вашингтон, а не Марта ИЛИ Собака '

И упрощая это до:

A = George 
B = Washington
C = Martha
D = Dog
& = AND
! = NOT
| = OR

Мы получили бы постфиксную запись

AB & C D |!

Что означает:

  1. Push-значение A (Джордж)
  2. Push-значение B (Вашингтон)
  3. И, вытолкнув два предыдущих значения и подталкивая результат (Джордж И Вашингтон)
  4. Push-значение C (Марта)
  5. НЕ, выталкивая два предыдущих значения и подталкивая результат (Джордж И Вашингтон) НЕ (Марта)
  6. Push-значение D (собака)
  7. ИЛИ, вытолкнув два предыдущих значения и подталкивая результат ((Джордж И Вашингтон) НЕ (Марта)) ИЛИ (Собака)
3 голосов
/ 09 июля 2010

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

string input = "George Washington AND NOT Martha OR Dog";

private string interpretSearchQuery(string input)
{
    StringBuilder builder = new StringBuilder();
    var tokens = input.Split( ' ' );

    bool quoteOpen = false;
    foreach( string token in tokens )
    {
        if( !quoteOpen && !IsSpecial( token ) )
        {
            builder.AppendFormat( " \"{0}", token );
            quoteOpen = true;
        }
        else if( quoteOpen && IsSpecial( token ))
        {
            builder.AppendFormat( "\" {0}", token );
            quoteOpen = false;
        }
        else
        {
            builder.AppendFormat( " {0}", token );
        }
    }

    if( quoteOpen )
    {
        builder.Append( "\"" );
    }

    return "'" + builder.ToString().Trim() + "'";
}

public static bool IsSpecial( string token )
{
    return string.Compare( token, "AND", true ) == 0 ||
        string.Compare( token, "OR", true ) == 0 ||
        string.Compare( token, "NOT", true ) == 0;
}
0 голосов
/ 09 июля 2010

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

private string interpretSearchTerm(string searchTerm)
        {
            string term = "";
            /* replace ' AND ' | ' AND NOT ' with
             * " AND "
             * " AND NOT "
             * 
             * replace ' OR ' | ' OR NOT ' with
             * " OR "
             * " OR NOT "
             * 
             * add " to beginning of string and " to end of string
             */
            if (searchTerm.IndexOf("AND") > -1
                || searchTerm.IndexOf("OR") > -1
                || searchTerm.IndexOf("AND NOT") > -1
                || searchTerm.IndexOf("OR NOT") > -1)
            {
                term = searchTerm.Replace(" AND NOT ", "\"AND NOT\"")
                        .Replace(" AND ", "\"AND\"")
                        .Replace(" OR NOT", "\"OR NOT\"")
                        .Replace(" OR ", "\"OR\"");
                term = "\"" + term + "\"";
                return term;
            }
            else if (searchTerm.IndexOf("\"") > -1) return searchTerm;
            else return "\"" + searchTerm + "\"";
        }

Теперь я перейду к реализации алгоритма постфикса, предложенного GalacticJello.Я опубликую это, когда у меня получится.

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