Как мне реализовать «фонетический» поиск

В настоящее время я пытаюсь улучшить свой алгоритм поиска.

Для лучшего понимания, вот текущая логика, лежащая в основе этого:
у нас есть объекты с прикрепленными n ключевыми словами в db. в базе данных это решается с помощью 2 таблиц ( Объект , Ключевое слово ), где таблица Ключевое слово имеет FK для объекта . Когда я строю свои деревья поиска, я создаю строковое значение (объявление: удалить умляуты, преобразовать в нижний регистр, ...) всех ключевых слов объекта. та же процедура преобразования ( NormalizeSearchPattern () ) выполняется с шаблонами поиска. Я поддерживаю И -поиск и ключевые слова с минимальной длиной только 2 символа!

Алгоритм поиска в настоящее время является вариантом быстрого обратного поиска (этот пример не оптимизирован):

bool IsMatch(string source, string searchPattern)
{
    // example:
    // source: "hello world"
    // searchPattern: "hello you freaky funky world"
    // patterns[]: { "hello", "you", "freaky", "funky", "world" }

    searchPattern = NormalizeSearchPattern(searchPattern);
    var patterns = MagicMethodToSplitPatternIntoPatterns(searchPattern);
    foreach (var pattern in patterns)
    {
        var success = false;
        var patternLength = pattern.Length;
        var firstChar = pattern[0];
        var secondChar = pattern[1];

        var lengthDifference = input.Length - patternLength;
        while (lengthDifference >= 0)
        {
            if (source[lengthDifference--] != firstChar)
            {
                continue;
            }
            if (source[lengthDifference + 2] != secondChar)
            {
                continue;
            }

            var l = lengthDifference + 3;
            var m = 2;
            while (m < patternLength)
            {
                if (input[l] != pattern[m])
                {
                    break;
                }
                l++;
                m++;
            }

            if (m == patternLength)
            {
                success = true;
            }
        }
        if (!success)
        {
            return false;
        }
    }
    return true;
}

Нормализация выполняется с помощью (этот пример не оптимизирован)

    string RemoveTooShortKeywords(string keywords)
    {
        while (Regex.IsMatch(keywords, TooShortKeywordPattern, RegexOptions.Compiled | RegexOptions.Singleline))
        {
            keywords = Regex.Replace(keywords, TooShortKeywordPattern, " ", RegexOptions.Compiled | RegexOptions.Singleline);
        }

        return keywords;
    }

    string RemoveNonAlphaDigits(string value)
    {
        value = value.ToLower();
        value = value.Replace("ä", "ae");
        value = value.Replace("ö", "oe");
        value = value.Replace("ü", "ue");
        value = value.Replace("ß", "ss");

        return Regex.Replace(value, "[^a-z 0-9]", " ", RegexOptions.Compiled | RegexOptions.Singleline);
    }

    string NormalizeSearchPattern(string searchPattern)
    {
        var resultNonAlphaDigits = RemoveNonAlphaDigits(searchPattern);
        var resultTrimmed = RemoveTooShortKeywords(resultNonAlphaDigits);
        return resultTrimmed;
    }

Итак, это довольно прямолинейно, поэтому очевидно, Это приложение выполнено на C #, оно хранит деревья поиска и объекты в статической переменной (чтобы запросить базу данных только один раз при инициализации), производительность должна быть выдающейся (в настоящее время 500 000 lineValues ​​запрашиваются менее чем за 300 мсек).

5
задан Martin Thorsen Ranang 10 November 2015 в 21:25
поделиться