13.4. Using virtual list view control to request a contiguous subset of a large search result

Directory Server supports the LDAP virtual list view control. This control enables an LDAP client to request a contiguous subset of a large search result.
For example, you have stored an address book with 100.000 entries in Directory Server. By default, a query for all entries returns all entries at once. This is a resource and time-consuming operation, and clients often do not require the whole data set because, if the user scrolls through the results, only a partial set is visible.
However, if the client uses the VLV control, the server only returns a subset and, for example, if the user scrolls in the client application, the server returns more entries. This reduces the load on the server, and the client does not need to store and process all data at once.
VLV also improves the performance of server-sorted searches when all search parameters are fixed. Directory Server pre-computes the search results within the VLV index. Therefore, the VLV index is much more efficient than retrieving the results and sorting them afterwards.
In Directory Server, the VLV control is always available. However, if you use it in a large directory, a VLV index, also called browsing index, can significantly improve the speed.
Directory Server does not maintain VLV indexes for attributes, such as for standard indexes. The server generates VLV indexes dynamically based on attributes set in entries and the location of those entries in the directory tree. Unlike standard entries, VLV entries are special entries in the database.

13.4.1. How the VLV control works in ldapsearch commands

Typically, you use the virtual list view (VLV) feature in LDAP client applications. However, for example for testing purposes, you can use the ldapsearch utility to request only partial results.
To use the VLV feature in ldapsearchcommands, specify the -E option for both the sss (server-side sorting) and vlv search extensions:
# ldapsearch ... -E 'sss=attribute_list' -E 'vlv=query_options'
The sss search extension has the following syntax:
[!]sss=[-]<attr[:OID]>[/[-]<attr[:OID]>...]
The vlv search extension has the following syntax:
[!]vlv=<before>/<after>(/<offset>/<count>|:<value>)
  • before sets the number of entries returned before the targeted one.
  • after sets the number of entries returned after the targeted one.
  • index, count, and value help to determine the target entry. If you set value, the target entry is the first one having its first sorting attribute starting with the value. Otherwise, you set count to 0, and the target entry is determined by the index value (starting from 1). If the count value is higher than 0, the target entry is determined by the ratio index * number of entries / count.

Example 13.1. Output of an ldapsearch command with VLV search extension

The following command searches in ou=People,dc=example,dc=com. The server then sorts the results by the cn attribute and returns the uid attributes of the 70th entry together with one entry before and two entries after the offset.
# 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.
For additional details, see the -E parameter description in the ldapsearch(1) man page.

13.4.2. Enabling unauthenticated users to use the VLV control

By default, the access control instruction (ACI) in the oid=2.16.840.1.113730.3.4.9,cn=features,cn=config entry enables only authenticated users to use the VLV control. To enable also non-authenticated users to use the VLV control, update the ACI by changing userdn = "ldap:///all" to userdn = "ldap:///anyone".

Procedure

  • Update the ACI in oid=2.16.840.1.113730.3.4.9,cn=features,cn=config:
    # 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";)

Verification

  • Perform a query with VLV control not specify a bind user:
    # 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
    This command requires that the server allows anonymous binds.
    If the command succeeds but returns no entries, run the query again with a bind user to ensure that the query works when using authentication.

13.4.3. Creating a VLV index using the command line to improve the speed of VLV queries

Follow this procedure to create a virtual list view (VLV) index, also called browsing index, for entries in ou=People,dc=example,dc=com that contain a mail attribute and have the objectClass attribute set to person.

Prerequisites

  • Your client applications use the VLV control.
  • Client applications require to query a contiguous subset of a large search result.
  • The directory contains a large number of entries.

Procedure

  1. Create the VLV search entry:
    # 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
    This command uses the following options:
    • --name sets the name of the search entry. This can be any name.
    • --search-base sets the base DN for the VLV index. Directory Server creates the VLV index on this entry.
    • --search-scope sets the scope of the search to run for entries in the VLV index. You can set this option to 0 (base search), 1 (one-level search), or 2 (subtree search).
    • --search-filter sets the filter Directory Server applies when it creates the VLV index. Only entries that match this filter become part of the index.
    • userRoot is the name of the database in which to create the entry.
  2. Create the index entry:
    # 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
    This command uses the following options:
    • --index-name sets the name of the index entry. This can be any name.
    • --parent-name sets the name of the VLV search entry and must match the name you set in the previous step.
    • --sort sets the attribute names and their sort order. Separate the attributes by space.
    • --index-it causes that Directory Server automatically starts an index task after the entry was created.
    • dc=example,dc=com is the suffix of the database in which to create the entry.

Verification

  1. Verify the successful creation of the VLV index in the /var/log/dirsrv/slapd-instance_name/errors file:
    [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. Use the VLV control in an ldapsearch command to query only specific records from the directory:
    # 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
    This example assumes you have entries continuously named uid=user001 to at least uid=user072 in ou=People,dc=example,dc=com.
For additional details, see the -E parameter description in the ldapsearch(1) man page.

13.4.4. Creating a VLV index using the web console to improve the speed of VLV queries

Follow this procedure to create a virtual list view (VLV) index, also called browsing index, for entries in ou=People,dc=example,dc=com that contain a mail attribute and have the objectClass attribute set to person.

Prerequisites

  • Your client applications use the VLV control.
  • Client applications require to query a contiguous subset of a large search result.
  • The directory contains a large number of entries.

Procedure

  1. Open the Directory Server user interface in the web console. See Section 1.4, “Logging Into Directory Server Using the Web Console”.
  2. Navigate to DatabaseSuffixesdc=example,dc=comVLV Indexes
  3. Click Create VLV Index and fill the fields:
    Creating a VLV Index Using the Web Console

    Figure 13.1. Creating a VLV Index Using the Web Console

  4. Enter the attribute names, and click Add Sort Index.
  5. Select Index VLV on Save.
  6. Click Save VLV Index.

Verification

  1. Navigate to 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. Use the VLV control in an ldapsearch command to query only specific records from the directory:
    # 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
    This example assumes you have entries continuously named uid=user001 to at least uid=user072 in ou=People,dc=example,dc=com.
For additional details, see the -E parameter description in the ldapsearch(1) man page.