現在、私は検索アルゴリズムを強化しようとしています。"音標的"な検索を実装するにはどうすればいいですか
理解を深めるため、ここには現在のロジックがあります。
dbにn個のキーワードが関連付けられたオブジェクトがあります。データベースでは、これは2つのテーブル(Object
,Keyword
)によって解決され、Keyword
テーブルのFKはObject
です。私は自分のsearchtreesを構築しているときに、オブジェクトのすべてのキーワードの行の値(広告:ウムラウトを削除する、小文字に変換する、など)を作成します。同じ変換ルーチン(NormalizeSearchPattern()
)が検索パターンで実行されます。 AND
-searchとキーワードをサポートしています。最小長は2文字です。
検索アルゴリズムが(この例では、最適化されていません)現在fast-reverse-search
の変形である:
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;
}
だから、これはあります私がに実装したsource
とsearchPattern
のバリアント(上記のとおり、ウムラウト、大文字と小文字の違いなど)にしか対応できないことは明らかです。 。 - >「ハウザー
- 単数/複数
- misstyping(例えば "hauserr" <:それがダウンしていたときに しかし、私はアルゴリズムを強化すべきか(または
NormalizeSearchPattern()
)は非感受性が高いことが「) - ...
ただ、設計の詳細を知るために:このアプリは、C#で行われ
を、それは検索を保存します木やオブジェクトを静的変数に入れておくと(initで一度だけデータベースに問い合わせる)、パフォーマンスは優れていなければなりません(現在500.000行の値は300msec以内に照会されます)。
私のデモコードを詳しく教えてください。 –
一致する辞書が必要です。あなたに最初の辞書草案を得るためにウィキペディアをスキャンするだけで十分です。次に、これらすべての単語をbi(2)またはtri(3)グラムに分割します。 'Hello'は' hel'、 'ell'、' llo'です。単語をマッチさせるときは、それも分割するので、 'Helllo'は' Hel'、 'ell'、' lll'、 'llo'です。これらの一致を計算し、関連性によって並べ替えます。 'Helllo'は' Hello'にマッチしますが、他の言葉でも一致します。 – Arcturus
また、参照:http://en.wikipedia.org/wiki/N-gram – Arcturus