13.4. 仮想リストビューコントロールを使用して、大規模な検索結果の連続したサブセットを要求する

Directory Server は、LDAP 仮想リストビューコントロールをサポートしています。この制御により、LDAP クライアントは大規模な検索結果の連続したサブセットを要求できます。
たとえば、Directory Server に 100.000 エントリーのアドレス帳を保存したとします。デフォルトでは、すべてのエントリーのクエリーはすべてのエントリーを一度に返します。これはリソースと時間のかかる操作であり、ユーザーが結果をスクロールすると一部のセットしか表示されないため、クライアントはデータセット全体を必要としないことがよくあります。
ただし、クライアントが VLV コントロールを使用する場合、サーバーはサブセットのみを返します。たとえば、ユーザーがクライアントアプリケーションでスクロールすると、サーバーはさらに多くのエントリーを返します。これにより、サーバーの負荷が軽減され、クライアントはすべてのデータを一度に保存して処理する必要がなくなります。
すべての検索パラメーターが固定されている場合、VLV はサーバーでソートされた検索のパフォーマンスも向上させます。Directory Server は、VLV インデックス内の検索結果を事前に計算します。したがって、VLV インデックスは、結果を取得してから後で並べ替えるよりもはるかに効率的です。
Directory Server では、VLV コントロールは常に利用可能です。ただし、大きなディレクトリーで使用する場合は、ブラウジングインデックスとも呼ばれる VLV インデックスを使用すると、速度が大幅に向上します。
Directory Server は、標準インデックスなどの属性の VLV インデックスを維持しません。サーバーは、エントリーに設定された属性とディレクトリーツリー内のそれらのエントリーの場所に基づいて、VLV インデックスを動的に生成します。標準エントリーとは異なり、VLV エントリーはデータベース内の特別なエントリーです。

13.4.1. ldapsearch コマンドでの VLV コントロールの動作

通常、LDAP クライアントアプリケーションでは仮想リストビュー (VLV) 機能を使用します。ただし、たとえばテスト目的で、ldapsearch ユーティリティーを使用して部分的な結果のみを要求できます。
ldapsearch コマンドで VLV 機能を使用するには、sss (サーバー側の並べ替え) と vlv 検索拡張機能の両方に -E オプションを指定します。
# ldapsearch ... -E 'sss=attribute_list' -E 'vlv=query_options'
sss 検索拡張機能の構文は次のとおりです。
[!]sss=[-]<attr[:OID]>[/[-]<attr[:OID]>...]
vlv 検索拡張機能の構文は次のとおりです。
[!]vlv=<before>/<after>(/<offset>/<count>|:<value>)
  • before は、対象のエントリーの前に返されるエントリーの数を設定します。
  • after は、対象のエントリーの後に返されるエントリーの数を設定します。
  • indexcount、および value は、ターゲットエントリーの決定に役立ちます。value を設定すると、ターゲットエントリーは、その値で始まる最初の並べ替え属性を持つ最初のエントリーになります。それ以外の場合は、count0 に設定し、ターゲットエントリーは index 値 (1 から開始) によって決定されます。count 値が 0 より大きい場合、ターゲットエントリーは ratio index * number of entries / count によって決定されます。

例13.1 VLV 検索拡張機能を使用した ldapsearch コマンドの出力

次のコマンドは、ou=People,dc=example,dc=com を検索します。次に、サーバーは結果を cn 属性でソートし、70 番目のエントリーの uid 属性をオフセットの前の 1 つのエントリーと後の 2 つのエントリーとともに返します。
# ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -b "ou=People,dc=example,dc=com" -s one -x -E 'sss=cn' -E 'vlv=1/2/70/0' uid
# user069, People, example.com
dn: uid=user069,ou=People,dc=example,dc=com
uid: user069

# user070, People, example.com
dn: uid=user070,ou=People,dc=example,dc=com
uid: user070

# user071, People, example.com
dn: uid=user071,ou=People,dc=example,dc=com
uid: user071

# user072, People, example.com
dn: uid=user072,ou=People,dc=example,dc=com
uid: user072

# search result
search: 2
result: 0 Success
control: 1.2.840.113556.1.4.474 false MIQAAAADCgEA
sortResult: (0) Success
control: 2.16.840.1.113730.3.4.10 false MIQAAAALAgFGAgMAnaQKAQA=
vlvResult: pos=70 count=40356 context= (0) Success

# numResponses: 5
# numEntries: 4
Press [before/after(/offset/count|:value)] Enter for the next window.
詳細については、ldapsearch(1) man ページの -Eパラメーターの説明を参照してください。

13.4.2. 認証されていないユーザーが VLV コントロールを使用できるようにする

デフォルトでは、oid=2.16.840.1.113730.3.4.9,cn=features,cn=config エントリーのアクセス制御命令 (ACI) により、認証されたユーザーのみが VLV コントロールを使用できるようになります。認証されていないユーザーも VLV コントロールを使用できるようにするには、userdn = "ldap:///all"userdn = "ldap:///anyone" に変更して ACI を更新します。

手順

  • oid=2.16.840.1.113730.3.4.9,cn=features,cn=config の ACI を更新します。
    # ldapmodify -D "cn=Directory Manager" -W -H ldap://server.example.com -x
    
    dn: oid=2.16.840.1.113730.3.4.9,cn=features,cn=config
    changetype: modify
    replace: aci
    aci: (targetattr != "aci")(version 3.0; acl "VLV Request Control"; allow( read, search, compare, proxy ) userdn = "ldap:///anyone";)

検証

  • バインドユーザーを指定せずに、VLV コントロールでクエリーを実行します。
    # ldapsearch -H ldap://server.example.com -b "ou=People,dc=example,dc=com" -s one -x -E 'sss=cn' -E 'vlv=1/2/70/0' uid
    このコマンドでは、サーバーが匿名バインドを許可する必要があります。
    コマンドが成功してもエントリーが返されない場合は、バインドユーザーを使用してクエリーを再度実行し、認証の使用時にクエリーが機能することを確認します。

13.4.3. コマンドラインを使用して VLV インデックスを作成し、VLV クエリーの速度を向上させる

次の手順に従って、ou=People,dc=example,dc=com 内のエントリーに対して、ブラウジングインデックスとも呼ばれる仮想リストビュー (VLV) インデックスを作成します。mail属性を持ち、person に設定された objectClass 属性があります。

前提条件

  • クライアントアプリケーションは VLV コントロールを使用している。
  • クライアントアプリケーションでは、大規模な検索結果の連続したサブセットに対してクエリーを実行する必要がある。
  • ディレクトリーには多数のエントリーが含まれている。

手順

  1. VLV 検索エントリーを作成します。
    # dsconf -D "cn=Directory Manager" ldap://server.example.com backend vlv-index add-search --name "VLV People" --search-base "ou=People,dc=example,dc=com" --search-filter "(&(objectClass=person)(mail=*))" --search-scope 2 userRoot
    コマンドは、以下のオプションを使用します。
    • --name は検索エントリーの名前を設定します。これは任意の名前にすることができます。
    • --search-base VLV インデックスのベース DN を設定します。Directory Server は、このエントリーに VLV インデックスを作成します。
    • --search-scope は VLV インデックス内のエントリーに対して実行する検索の範囲を設定します。このオプションは、0 (ベース検索)、1 (1 レベル検索)、または 2 (サブツリー検索) に設定できます。
    • --search-filter は VLV インデックスの作成時に Directory Server が適用するフィルターを設定します。このフィルターに一致するエントリーのみがインデックスの一部になります。
    • userRoot は、エントリーを作成するデータベースの名前です。
  2. インデックスエントリーを作成します。
    # dsconf -D "cn=Directory Manager" ldap://server.example.com backend vlv-index add-index --index-name "VLV People - cn sn" --parent-name "VLV People" --sort "cn sn" --index-it dc=example,dc=com
    コマンドは、以下のオプションを使用します。
    • --index-name は、インデックスエントリーの名前を設定します。これは任意の名前にすることができます。
    • --parent-name は、VLV 検索エントリーの名前を設定し、前の手順で設定した名前と一致する必要があります。
    • --sort は属性名とソート順序を設定します。属性をスペースで区切ります。
    • --index-it は、エントリーの作成後に、Directory Server がインデックスタスクを自動的に開始します。
    • dc=example,dc=com は、エントリーを作成するデータベースの接尾辞です。

検証

  1. /var/log/dirsrv/slapd-instance_name/errors ファイルで VLV インデックスが正常に作成されたことを確認します。
    [26/Nov/2021:11:32:59.001988040 +0100] - INFO - bdb_db2index - userroot: Indexing VLV: VLV People - cn sn
    [26/Nov/2021:11:32:59.507092414 +0100] - INFO - bdb_db2index - userroot: Indexed 1000 entries (2%).
    ...
    [26/Nov/2021:11:33:21.450916820 +0100] - INFO - bdb_db2index - userroot: Indexed 40000 entries (98%).
    [26/Nov/2021:11:33:21.671564324 +0100] - INFO - bdb_db2index - userroot: Finished indexing.
  2. ldapsearch コマンドで VLV コントロールを使用して、ディレクトリーから特定のレコードのみをクエリーします。
    # ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -b "ou=People,dc=example,dc=com" -s one -x -E 'sss=cn' -E 'vlv=1/2/70/0' uid
    # user069, People, example.com
    dn: uid=user069,ou=People,dc=example,dc=com
    cn: user069
    
    # user070, People, example.com
    dn: uid=user070,ou=People,dc=example,dc=com
    cn: user070
    
    # user071, People, example.com
    dn: uid=user071,ou=People,dc=example,dc=com
    cn: user071
    
    # user072, People, example.com
    dn: uid=user072,ou=People,dc=example,dc=com
    cn: user072
    この例では、ou=People,dc=example,dc=com にuid=user001 から少なくとも uid=user072 まで連続して名前が付けられたエントリーがあることを前提としています。
詳細については、ldapsearch(1) man ページの -Eパラメーターの説明を参照してください。

13.4.4. Web コンソールを使用して VLV インデックスを作成し、VLV クエリーの速度を向上させる

次の手順に従って、ou=People,dc=example,dc=com 内のエントリーに対して、ブラウジングインデックスとも呼ばれる仮想リストビュー (VLV) インデックスを作成します。mail属性を持ち、person に設定された objectClass 属性があります。

前提条件

  • クライアントアプリケーションは VLV コントロールを使用している。
  • クライアントアプリケーションでは、大規模な検索結果の連続したサブセットに対してクエリーを実行する必要がある。
  • ディレクトリーには多数のエントリーが含まれている。

手順

  1. Web コンソールで Directory Server ユーザーインターフェイスを開きます。「Web コンソールを使用した Directory Server へのログイン」を参照してください。
  2. DatabaseSuffixesdc=example,dc=comVLV Indexes に移動します。
  3. Create VLV Index をクリックして、フィールドに入力します。

    図13.1 Web コンソールを使用した VLV インデックスの作成

    Web コンソールを使用した VLV インデックスの作成
  4. 属性名を入力し、Add Sort Index をクリックします。
  5. Index VLV on Save を選択します。
  6. Save VLV Index をクリックします。

検証

  1. MonitoringLoggingErrors Log に移動します。
    [26/Nov/2021:11:32:59.001988040 +0100] - INFO - bdb_db2index - userroot: Indexing VLV: VLV People - cn sn
    [26/Nov/2021:11:32:59.507092414 +0100] - INFO - bdb_db2index - userroot: Indexed 1000 entries (2%).
    ...
    [26/Nov/2021:11:33:21.450916820 +0100] - INFO - bdb_db2index - userroot: Indexed 40000 entries (98%).
    [26/Nov/2021:11:33:21.671564324 +0100] - INFO - bdb_db2index - userroot: Finished indexing.
  2. ldapsearch コマンドで VLV コントロールを使用して、ディレクトリーから特定のレコードのみをクエリーします。
    # ldapsearch -D "cn=Directory Manager" -W -H ldap://server.example.com -b "ou=People,dc=example,dc=com" -s one -x -E 'sss=cn' -E 'vlv=1/2/70/0' uid
    # user069, People, example.com
    dn: uid=user069,ou=People,dc=example,dc=com
    cn: user069
    
    # user070, People, example.com
    dn: uid=user070,ou=People,dc=example,dc=com
    cn: user070
    
    # user071, People, example.com
    dn: uid=user071,ou=People,dc=example,dc=com
    cn: user071
    
    # user072, People, example.com
    dn: uid=user072,ou=People,dc=example,dc=com
    cn: user072
    この例では、ou=People,dc=example,dc=com にuid=user001 から少なくとも uid=user072 まで連続して名前が付けられたエントリーがあることを前提としています。
詳細については、ldapsearch(1) man ページの -Eパラメーターの説明を参照してください。