VLVを使用した検索方法
Active Directoryは、仮想リストビュー (VLV) 検索をサポートしています。 このスタイルの検索は、大規模な結果セット用に特別に設計されており、アプリケーションでは、実際にすべてのエントリを取得することなく、数千のエントリのサブセットを表示できます。
VLV検索を使用するには、2つの異なる方法があります。 1つ目は、数値オフセットに基づいて特定のエントリの属性を取得する方法です。 このメソッドは、スクロール操作に応答して検索結果を取得する場合に便利です。
VLV検索を使用する2つ目の方法は、テキスト属性の一部またはすべてを検索し、検索結果のみを表示する方法です。 この使用例は、アドレス帳です。 ユーザーが 「s」 を入力すると、アプリケーションはVLV検索を使用して、 「s」 で始まる共通名を持つエントリを検索できます。 ユーザーが 「s」 に 「m」 を追加すると、アプリケーションは別のVLV検索を使用して、 「sm」 で始まる共通名を持つエントリを検索できます。
VLV検索を実行するには、VLVコントロールを使用するようにADSIに指示します。 これを行うには、ADSTYPE_PROV_SPECIFIC値を指定したADS_SEARCHPREF_VLV検索オプションを指定してIDirectorySearch :: SetSearchPreference メソッドを呼び出します。 ADSTYPE_PROV_SPECIFIC値は、検索に関するデータを含むADS_VLV構造体へのポインターです。 GetVLVItemCount関数の例は、これらの両方の検索設定を設定する方法を示しています。
すべてのVLV検索では、サーバー側の結果の並べ替えを使用する必要があります。これは、ADS_SEARCHPREF_SORT_ON検索設定を設定することによって実行されます。 ADS_SEARCHPREF_SORT_ON検索設定の詳細については、IDirectorySearchを使用した検索結果の並べ替えを参照してください。
VLV検索が実行されると、検索に関する特定の量のメタデータが、ADS_VLV_RESPONSE識別子を使用してIDirectorySearch :: GetColumnを呼び出すことによって取得される列に返されます。 このデータは、ADS_VLV構造体に含まれています。 特に重要なのは、dwContentCountメンバーとlpContextIDメンバーです。 dwContentCountメンバーには、VLV検索条件を満たす結果の数が含まれます。 この値は、その種類の検索に対して返される項目の合計数の推定値として使用できます。 lpContextIDメンバーには、検索を識別するために次の検索に渡すことができるサーバー定義の値が含まれています。 lpContextIDを使用すると、検索のパフォーマンスを向上させることができます。 lpContextIDはサーバー定義の値であり、その長さはdwContextIDLengthメンバーに含まれていることに注意してください。 このバッファーは、IDirectorySearch::FreeColumnメソッドが呼び出されたときに解放されるため、呼び出し元は適切なサイズのバッファーを割り当て、検索間でバッファーの内容をコピーして保存する必要があります。
LDAP VLVコントロールの詳細については、LDAP VLVコントロールを使用した検索を参照してください。
詳細については、以下を参照してください:
- 項目数の取得
- オフセットによる検索
- 文字列による検索
- VLV検索を使用するためのコード例
項目数の取得
特定の検索で返される項目数の推定値を取得するには、次の手順を実行します。
ADS_VLV構造体に、すべての0またはNULL値を入力します。
ADS_SEARCHPREF_INFOに次の値を入力します。
IDirectorySearchを使用して検索結果を並べ替える に示すように、ADS_SORTKEY構造体に入力して、目的の属性で並べ替えます。
別のADS_SEARCHPREF_INFOに入力して、IDirectorySearchを使用して検索結果を並べ替えるに示すように、ADS_SORTKEY構造体を検索設定に追加します。
その他の必要な検索設定を追加し、IDirectorySearch::SetSearchPreferenceを呼び出して検索設定を設定します。
IDirectorySearch :: ExecuteSearchを使用して検索を実行します。
IDirectorySearch :: GetFirstRowを呼び出して、結果の最初の行を取得します。
ADS_VLV_RESPONSEを使用してIDirectorySearch :: GetColumnを呼び出して、VLV検索メタデータを取得します。
ADS_SEARCH_COLUMN構造体のpADsValues->ProviderSpecific.lpValueをADS_VLV構造体ポインターにキャストします。 このADS_VLV構造体のdwContentCountメンバーには、その型の検索によって返される項目の概数が含まれています。
同じ種類の他のVLV検索が実行される場合は、lpContextIDデータのコピーを作成し、次のVLV検索用に保持します。
GetVLVItemCount関数の例は、この方法を示しています。
オフセットによる検索
VLV検索が非常に高速になるのは、数値オフセットによって特定の結果を検索できることです。 たとえば、検索によって1万項目が返される場合、VLV検索を使用すると、対象の項目の前にすべての項目を取得しなくても、約4072番目の項目の情報を取得できます。
オフセットは、オフセットとコンテンツ数の比率として指定されます。 比率は、サーバーがリスト内に存在するエントリ数の正確な推定値を持っていない場合や、ユーザーが参照している間にリストのサイズが変化する可能性があるために役立ちます。 リストの先頭と末尾を示す必要があるため、最初の検索要求でコンテンツ数の推定値をオフセット値と共に使用できます。 サーバーは、このデータを使用して、コンテンツ数のアイデアに基づいて、リスト内の対応するオフセットを計算します。これは、ADS_VLV構造体のdwContentCountメンバーを介してクライアントに応答で送信されます。 たとえば、リストのサイズを3000と推定し、オフセットをリストエントリ1500にする場合は、dwContentCountを3000に設定し、dwOffsetを1500に設定します。 サーバーが実際のリストサイズを4500と推定する場合は、オフセットを2250に再計算し、dwContentCountとdwOffsetで新しい推定値を返します。
Note
VLV検索のすべての数値は近似値であり、絶対値には使用しないでください。 たとえば、100の比率で50番目の項目に対してVLV検索を発行した場合、正確な中間項目を取得することは保証されません。
オフセットによって特定の項目を検索するには、次の手順を実行します。
ADS_VLV構造体に次の値を入力します。 構造体の追加のメンバーは、0またはNULLに設定する必要があります。
- dwContentCountメンバーを、取得する項目の比率の最大値に設定します。
- dwOffsetメンバーを、取得する項目のdwContentCountを基準とした比率に設定します。
- lpContextIDメンバーをコンテキストIDバッファーのコピーのアドレスに設定し、dwContextIDLengthをコンテキストIDバッファーの長さ (バイト単位) に設定します。 コンテキストIDが保存されていない場合は、これらのメンバーの両方を0またはNULLにする必要があります。
「項目数を取得する」 の手順2~5に示すように、検索設定を設定します。
IDirectorySearch :: ExecuteSearchを使用して検索を実行します。
IDirectorySearch :: GetFirstRowを呼び出して、結果の最初の行を取得します。
要求された項目の実際のデータを取得するには、取得する属性の名前を指定してIDirectorySearch :: GetColumnを呼び出します。
ADS_VLV_RESPONSEを使用してIDirectorySearch :: GetColumnを呼び出して、VLV検索メタデータを取得します。
ADS_SEARCH_COLUMN構造体のpADsValues->ProviderSpecific.lpValueをADS_VLV構造体ポインターにキャストします。
lpContextIDデータのコピーを作成し、次のVLV検索のために保持します。
GetVLVItemTextサンプル関数は、この方法を示しています。
また、1回の検索呼び出しで複数行のデータを取得することもできます。 これを行うには、手順1.でADS_VLV構造体のdwBeforeCountメンバーとdwAfterCountメンバーを適切に設定します。 dwBeforeCountメンバーには、対象の項目の前にリストに表示される項目の数が含まれ、dwAfterCountメンバーには、対象の項目の後にリストに表示される項目の数が含まれます。 これらのカウントはどちらも項目自体を除外するため、dwBeforeCountを10に設定し、dwAfterCountを10に設定すると、合計21個の項目が返されます。 このオプションを使用すると、クライアント側で検索結果をキャッシュできます。
文字列による検索
また、VLV検索を使用して、すべての項目を取得しなくても、値が文字列のすべてまたは一部と一致する文字列属性を持つ項目を検索することもできます。 文字列の照合は、ADS_SEARCHPREF_SORT_ON検索設定のADS_SORTKEY構造体で指定された属性に対して実行されます。
文字列で特定の項目を検索するには、次の手順を実行します。
ADS_VLV構造体に次の値を入力します。 構造体の追加のメンバーは、0またはNULLに設定する必要があります。
- pszTargetメンバーを、検索する文字列を含むNULLで終わる文字列へのポインターに設定します。
- lpContextIDメンバーをコンテキストIDバッファーのコピーのアドレスに設定し、dwContextIDLengthをコンテキストIDバッファーの長さ (バイト単位) に設定します。 コンテキストIDが保存されていない場合は、これらのメンバーの両方を0またはNULLにする必要があります。
「項目数を取得する」 の手順2~5に示すように、検索設定を設定します。
IDirectorySearch :: ExecuteSearchを使用して検索を実行します。
IDirectorySearch :: GetFirstRowを呼び出して、結果の最初の行を取得します。
要求された項目の実際のデータを取得するには、取得する属性の名前を指定してIDirectorySearch :: GetColumnを呼び出します。
ADS_VLV_RESPONSEを使用してIDirectorySearch :: GetColumnを呼び出して、VLV検索メタデータを取得します。
ADS_SEARCH_COLUMN構造体のpADsValues->ProviderSpecific.lpValueをADS_VLV構造体ポインターにキャストします。
lpContextIDデータのコピーを作成し、次のVLV検索のために保持します。 必要に応じて、dwOffsetメンバーには、文字列属性がpszTargetで指定された値で始まる最初の項目の1から始まるインデックスが含まれます。
GetVLVItemsByStringサンプル関数は、この方法を示しています。
インデックスによる検索と同様に、1回の検索呼び出しで複数行のデータを取得することもできます。 これは、ADS_VLV構造体のdwBeforeCountおよびdwAfterCountメンバーを適切に設定することによって、同じ方法で実現されます。