Microsoft では、さまざまな言語のワード ブレーカーとステマーを提供しています。 このトピックでは、言語用のカスタム ワード ブレーカーとステマー、および Microsoft が提供するロケール以外のロケールを実装し、使用する方法について説明します。
注
カスタム ワード ブレーカーは一時的にサポートされていませんでした。 2018 年 7 月に Windows Server 2019 に変更が加えられたので、Microsoft 署名のない DLL が SearchIndexer.exeによって読み込まれませんでした。 この制限は 2021 年 1 月に解除されました。
このトピックは次のように構成されています。
言語リソース DLL の登録
各言語リソース DLL は、次のエントリ ポイントを実装してエクスポートする必要があります。 DLL は任意のフォルダーに登録できます。
- DllMain は、DLL への標準エントリ ポイントです。
- DllRegisterServer は、次のように DLL をレジストリに登録します。
regsvr32.exe %SystemRoot%\MyFolder\wordbreaker.dll - DllCanUnloadNow を使用すると、クライアントはコンポーネント オブジェクト モデル (COM) を介してこのエントリ ポイントを呼び出して、言語リソース DLL をアンロードできるかどうかを判断できます。
- DllUnRegisterServer は、レジストリから DLL を削除します。
言語の登録
レジストリには、インデックスを作成する言語の言語固有のエントリが含まれており、これらのエントリは、言語固有のインデックス作成およびクエリ プロセスの部分を制御します。 これらのレジストリ エントリは、次のレジストリ キーの下にあります。
HKEY_LOCAL_MACHINE
SYSTEM
CurrentControlSet
ContentIndex
Control
Language
「Word Beaker」の実装
ワード ブレーカーは IWordBreaker を実装します。 IWordBreaker::BreakText メソッドは、すべてのテキスト処理と解析を実行します。 ワード ブレーカー コンポーネントを実装するには、言語のヒューリスティックが必要です。 これには、構文と形態に関する情報が含まれます。 除外または含める単語の一覧が必要な場合もあります。 除外された単語の一覧から、言語ロケールのノイズ ワードのファイルを作成します。 言語に関する考慮事項と、これらの考慮事項がワード ブレーカーの実装に与える影響の詳細については、「 言語と Unicode の考慮事項」を参照してください。
IWordBreaker::BreakText の主な目的は、すべてのテキストが処理されるまで、またはワード ブレーカーでエラーが発生するまで、TEXT_SOURCEからテキストを継続的に処理することです。 このデータ処理ループでは、 IWordBreaker::BreakText は、そのプロセスに対して特定のタスクを実行する解析メソッドとユーティリティ メソッドを呼び出します。 たとえば、ドイツ語のワード ブレーカーは複合語を処理するのに対し、フランス語のワード ブレーカーでは 分音記号 や clitic を処理できます。 ワード ブレーカーが実行する特定の関数と、これらのタスクの実行に使用する戦略は、その言語の要件によって完全に異なります。
テキストを分割する場合、ワード ブレーカーは、複数の表現を持つ可能性がある単語の "代替" フォームを識別します。 生成された単語間にセマンティックリレーションシップは暗黙的に示されません。 実際、元の単語は代替候補の一覧に含まれていない可能性があります。 代替フォームは、元の単語と同じ位置にインデックスに保存され、同じであることを示します。
文書がインデックスに含まれている場合、各単語には、オフセットを表す整数値、または文書の先頭からの単語の距離が割り当てられます。 クエリ内の単語間の相対距離は、フルテキスト インデックスに格納されているオフセットと比較されます。 クエリ "Where is Kyle's document" は、"Where" がオフセット n、"is" が n+1、"Kyle's" が n+2、"document" が n+3 のドキュメントと一致します。 "データ ベースに Kyle のドキュメントが提出されている場所" は次のように表されます。
| Where | is | カイル・カイルズ |
ドキュメント | 提出 | で | ザ | データベース データ ベース |
この例では、ワード ブレーカーはインデックスに "Kyle" ("Kyle's") と "database" ("data base") の代替形式を格納します。 ワード ブレーカーは、インデックス作成プロセス中に次の条件下で代替単語を生成して格納します。
- 代替単語がクエリ内で 1 つの単語として表示される可能性が高い場合
- ステミングアルゴリズムが代替語から元の単語を導き出す可能性が低い場合
代替単語形式を生成すると、次のバリエーションに示すように、クエリが文を表し、一致する方法の数が増えます。
- Kyle ドキュメントがデータベースにファイルされている場所
- Kyle のドキュメントがデータベースに提出されている場所
- データ ベースに Kyle ドキュメントが提出されている場所
- データ ベースに Kyle のドキュメントが提出されている場所
WordSink と PhraseSink
ワード ブレーカーでは 、IWordSink オブジェクトと IPhraseSink オブジェクトを使用して、テキストから抽出したすべての単語と語句を収集して格納します。 ワード ブレーカーは、文書内の元の単語フォームにできるだけ近いフォームに単語を格納します。 IPhraseSink では、クエリ時にフレーズが格納されます。 語句は、単語のシーケンスが長いほどまれで、小さい語句よりも区別が大きくなるため、クエリ結果の関連性が向上します。 インデクサーは、クエリ時に IPhraseSink に語句を配置すると、ワード ブレーカーのインスタンスを作成して語句を単語に分割します。 その後、インデクサーは、語句内の単語がインデックス内の互いに隣接しているかどうかを確認して、フレーズを評価します。 たとえば、インデックスの x、x+1、x+2、x+3 の位置に "ABCD" が発生する場合、クエリで "ABCD" のどの隣接する部分文字列が送信されても語句の一致が発生します。 この方法は、インデックス作成時に語句と長い単語を分割し、クエリ時間中に語句を生成する文字ベースのワード ブレーカーに有効です。
改
区切りは単語間のスペースです。 空白、句読点、書式設定、または言語自体の性質だけでは、中断が発生する可能性があります。 インデクサーで使用される区切りには、単語の終わり (EOW)、文末 (EOS)、段落の終わり (EOP) と章の終わり (EOC) の 4 種類があります。 EOW 区切りは既定の中断です。 各トークンの後、各区切りは、両側の単語間の異なるセマンティック距離を示します。 EOW で区切られた単語には、最も緊密なセマンティック リンクがあり、その後に EOS、EOP、EOC が続きます。 IWordSink::P utBreak への複数の呼び出しは累積され、null 単語または文の挿入に似ています。
スケーラビリティ、パフォーマンス、およびセキュリティ
ワード ブレーカーが同時呼び出しに応答する方法は、主にスレッド モデルの選択によって決まります。 インデクサーはシングル スレッド アプリケーションです。 ワード ブレーカーをシングル スレッド環境で動作させるには、ワード ブレーカーを "無料" または "両方" のスレッド モデルを使用して記述する必要があります。 ワード ブレーカーは、"アパートメント" スレッド モデルを使用して COM に登録しないでください。
ワード ブレーカーはグローバルな状態を回避し、ワード ブレーカーのインスタンスにデータを格納することをお勧めします。 ワード ブレーカーの実装に格納する必要があるコンテンツは、パラメーター fQuery と ulMaxTokenSize のみです。 単語区切りは、英語の単語区切りによって確立されたベンチマークの2倍以上遅くなってはいけません。 ワード ブレーカーのパフォーマンスも、ハードウェア機能を強化して向上させる必要があります。
インデクサーのワード ブレーカーは、ローカル システムのセキュリティ コンテキストで実行されます。 バッファーを管理し、正しくスタックするように記述する必要があります。 バッファー オーバーランから保護するには、すべての文字列コピーに明示的なチェックが必要です。 常にバッファーの割り当てられたサイズを確認し、バッファーのサイズに対してデータのサイズをテストする必要があります。 ワードブレーカーでは、IWordBreaker::BreakText メソッドに渡されたテキストが整形式であると想定することはできません。 ワード ブレーカーのトラブルシューティングの詳細については、「 言語リソースとベスト プラクティスのトラブルシューティング」を参照してください。
ステマーの実装
ステマーは IStemmer インターフェイスを実装します。 IStemmer::GenerateWordForms メソッドは、特定の入力単語の変更された単語フォームの一覧を生成します。 ステマー コンポーネントを実装するには、言語のヒューリスティックが必要です。 これには形態に関する情報が含まれます。 除外または含める単語の一覧が必要な場合もあります。 言語上の考慮事項と、これらの考慮事項がステマーの実装に与える影響の詳細については、「 言語および Unicode の考慮事項」を参照してください。
ステマーは、単語に対して属格または所有格を生成しないことを推奨します。 たとえば、"David" は "David' の代替フォームとして生成されません。ワード ブレーカーは、"David" と "David's" の両方を解析するときに生成されます。
ステマーは 、IWordFormSink オブジェクトを使用して代替単語の一覧を収集します。 IWordFormSink::PutWord は、ステミングエンジンから最終の単語を生成します。 いずれの場合も、この最後の単語は IStemmer::GenerateWordForms の入力単語と同じです。 たとえば、"swim" という単語を指定すると、ステマーは IWordFormSink::P utAltWord の呼び出しを通じて、"swimming"、"swimmer"、"swims"、"swam"、"swum" という単語形式を生成します。 ステマーは IWordFormSink::PutWord を介して "swim" を生成します。
スケーラビリティ、パフォーマンス、およびセキュリティ
ステマーはワード ブレーカーと同様に、"無料" スレッド モデルを使用し、スレッド モデルを "free" または "both" に設定して COM に登録する必要があります。Windows Search は、異なるスレッドからステマーの個別のインスタンスを同時に呼び出します。 したがって、ステマーには最小限のインスタンス データが必要です。
ステマーの精度は、クエリの関連性に大きな影響を与えます。 ステマーがテキストを誤ってステミングした場合、クエリは予測不可能で不正確な結果を返す可能性があります。 ステマーは、クエリのパフォーマンスに悪影響を与えることなく、1 秒あたり数百のクエリを処理する必要があります。 ステマーのパフォーマンスは、ハードウェア機能を強化して向上させる必要があります。 ステマーのトラブルシューティングの詳細については、「 言語リソースとベスト プラクティスのトラブルシューティング」を参照してください。
Windows Search のステマーは、ローカル セキュリティ コンテキストで実行されます。 バッファーを管理し、正しくスタックするように記述する必要があります。 バッファー オーバーランから保護するには、すべての文字列コピーに明示的なチェックが必要です。 常にバッファーの割り当てられたサイズを確認し、バッファーのサイズに対してデータのサイズをテストする必要があります。
関連トピック