文字マッチング
文字マッチングは負荷が高く、常に O(NP) になります。ここで、N = 検索する文字数、P = 検索する用語数です。
これは、線形検索の疑似コードです。
function linear_search(items, terms, match_mode) {
matched_items = new array();
for(item_idx=0, item_count=count(items);item_idx < item_count;++item_idx) {
doc = items[item_idx];
match_count = 0;
for(term_idx=0, term_count=count(terms);term_idx < term_count;++term_idx) {
term = terms[term_idx];
for(i=0, doc_len = strlen(doc), term_len = strlen(term) ; i < doc_len; i += term_len) {
if(substr(doc, i, term_len) == term) {
if(mode == 'ANY') {
matched_items[]=item_idx;
continue 3;
}
++match_count;
break;
}
}
}
if(mode == 'ALL' && (match_count == count(items)) matched_items[]=item_idx;
}
return matched_items;
}
各ドキュメント (行) は線形検索操作を使用して検索する必要があるため、N は実際にはデータ セット全体の sum(strlen(N)) です (各行、つまりドキュメントは N です)。O(NP) は、大規模なドキュメント、または多数のドキュメント、またはその両方に対する非常に長い操作です。
逆インデックス (トークン検索)
一方、トークン ベースの検索では、データをトークンに事前解析し、「逆インデックス」を作成します。各文書 (検索対象のテキスト) はまず用語に分割され、次に用語が索引付けされて文書を指します。
たとえば、生データが与えられた場合:
1, the quick brown fox
2, all cows eat grass
3, all the world
逆索引が作成されます。
all => 2, 3
brown => 1
cows => 2
eat => 2
fox => 1
grass => 2
quick => 1
the => 1, 3
world => 3
通常、b ツリーはトークンに対して作成されます。したがって、トークンのルックアップは O(log(N)) であり、トークンに一致するドキュメントのリストを取得します。実際のデータを取得するためのルックアップは、通常、別の O(log(N)) 操作です。
これにより、B ツリー構造を想定して、逆インデックス操作のコスト計算が行われます。
O(log(TERM_COUNT)) + O(log(DOC_MATCH_COUNT))
単語位置分析
通常、インデックスには、一致した文書とともに、文書内の単語位置が格納されます。これにより、ドキュメント自体を調べることなく、「bar」の近くの「foo」などの位置分析が可能になります。
all => 2:1, 3:1
brown => 1:3
cows => 2:2
eat => 2:3
fox => 1:4
grass => 2:4
quick => 1:2
the => 1:1, 3:2
world => 3:3
ステミング
さらに、Porter Stemmer (http://en.wikipedia.org/wiki/Stemming) などの「ステミング」は、通常、インデックス作成前および検索前に用語に適用されます。
ステマーは、「branded」や「branding」などの単語を「brand」に変換し、ブランドを検索すると、branded、branding、または brand に一致するドキュメントが返されるようにします。