В настоящее время я пытаюсь улучшить свой алгоритм поиска.
Для лучшего понимания, вот текущая логика, лежащая в основе этого:
у нас есть объекты с прикрепленными 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 мсек).