如何使用 VLV 进行搜索

Active Directory 支持 VLV 搜索 (虚拟) 视图。 这种搜索样式专为大型结果集设计,使应用程序能够显示数千个条目的子集,而无需实际检索每个条目。

VLV 搜索有两种不同的使用方式。 第一种是基于数值偏移量检索特定条目的属性。 在检索搜索结果以响应滚动操作时,此方法很有用。

使用 VLV 搜索的第二种方式是搜索部分或全部文本属性,并且仅显示搜索结果。 一个示例用法是通讯簿。 如果用户输入"s",则应用程序可以使用 VLV 搜索来搜索具有以"s"开头的公用名的条目。 如果用户随后将"m"添加到"s",则应用程序可以使用另一个 VLV 搜索来搜索具有以"sm"开头的公用名的条目。

若要执行 VLV 搜索,请指示 ADSI 使用 VLV 控件。 为此,请调用具有 ADS _ SEARCHPREF _ VLV 搜索选项且 ADSTYPE _ PROV _ 特定值的 IDirectorySearch::SetSearchPreference方法。 ADSTYPE _ PROV _ 特定 值是指向 ADS _ VLV结构的指针,其中包含有关搜索的数据。 GetVLVItemCount示例函数演示如何设置这两种搜索首选项。

所有 VLV 搜索都必须使用服务器端结果排序,这是通过设置 ADS _ SEARCHPREF _ SORT _ ON 搜索首选项执行的。 有关 ADS _ SEARCHPREF _ SORT _ ON 搜索首选项的信息,请参阅使用 IDirectorySearch对搜索结果进行排序。

执行 VLV 搜索时,在通过调用具有 ADS _ VLV _ RESPONSE 标识符的 IDirectorySearch::GetColumn检索的列中返回有关搜索的一定数量的元数据。 此数据包含在 ADS _ VLV 结构中。 特别重要的是 dwContentCountlpContextID 成员。 dwContentCount 成员将包含满足 VLV 搜索条件的结果数。 此值可以用作对搜索该类型返回的项总数的估计值。 lpContextID 成员包含服务器定义的值,该值可传递给下一个搜索以标识搜索。 使用 lpContextID 可以增强搜索性能。 请注意 ,lpContextID 是服务器定义的值,其长度包含在 dwContextIDLength 成员中。 调用 IDirectorySearch::FreeColumn 方法时将释放此缓冲区,因此调用方必须分配适当大小的缓冲区,并复制并保存搜索之间的缓冲区内容。

有关 LDAP VLV 控件的信息,请参阅 使用 LDAP VLV控件 进行搜索。

有关详细信息,请参阅:

获取项数

若要估算特定搜索将返回的项数,请执行以下步骤。

  1. 使用所有 零 _ 值或 NULL 值填充 ADS VLV 结构。

  2. 使用下列 值填充 ADS _ SEARCHPREF _ INFO。

    • dwSearchPref 成员 设置为 ADS _ SEARCHPREF _ VLV
    • vValue.dwType 成员 设置为 ADSTYPE _ PROV _ 特定
    • vValue.ProviderSpecific.dwLength 成员设置为 ADS _ VLV 结构的大小。
    • vValue.ProviderSpecific.lpValue 成员设置为步骤 1 中 ADS _ VLV 结构的地址。
  3. 填充 ADS _ SORTKEY 结构,如使用 IDirectorySearch 对搜索结果进行排序中所示,以根据所需属性进行排序。

  4. 填充另一 个 ADS _ SEARCHPREF _ INFO,ADS _ SORTKEY 结构添加到搜索首选项,如使用 IDirectorySearch对搜索结果进行排序中所示。

  5. 添加任何其他所需的搜索首选项并调用 IDirectorySearch::SetSearchPreference 以设置搜索首选项。

  6. 使用 IDirectorySearch::ExecuteSearch 执行搜索

  7. 通过调用 IDirectorySearch::GetFirstRow 获取结果的第一行

  8. 使用 ADS _ VLV _ RESPONSE 调用 IDirectorySearch::GetColumn以获取 VLV 搜索元数据。

  9. ADS SEARCH COLUMN 结构的 pADsValues->ProviderSpecific.lpValue 强制转换到 ADS _ VLV结构指针。 _ _ 此 ADS _ VLV 结构的 dwContentCount 成员包含该类型的搜索将返回的大致项数。

  10. 如果要执行相同类型的其他 VLV 搜索,请创建 lpContextID 数据的副本,并保留该数据供下一个 VLV 搜索使用。

GetVLVItemCount示例函数演示如何这样做。

按偏移量搜索

VLV 搜索速度如此快的一件事是,可以按数字偏移量搜索特定结果。 例如,如果搜索会导致返回 10,000 个项,则 VLV 搜索可以获取大约第 4072 项的信息,而无需检索有关项之前的所有项。

偏移量指定为偏移量和内容计数之间的比率。 比率很有用,因为服务器可能无法准确估计列表中存在的条目数,或者列表大小可能在用户浏览时发生变化。 由于必须指示列表的开头和结尾,因此可以在第一个搜索请求中对内容计数使用估计值以及偏移量值。 服务器使用此数据根据内容计数概念计算列表中的相应偏移量,该内容计数在响应中通过 ADS _ VLV结构的 dwContentCount 成员发送到客户端。 例如,如果将列表大小估计为 3000,并且希望偏移量是列表项 1500,则 dwContentCount 设置为 3000,dwOffset设置为 1500。 如果服务器将实际列表大小估计为 4500,它将重新计算偏移量到 2250,并返回 dwContentCountdwOffset 中的新估计值。

备注

VLV 搜索中所有数值都是近似值,不应用于绝对值。 例如,如果针对 100 以下第 50 项发出 VLV 搜索,则无法保证获得确切的中间项。

若要按偏移量搜索特定项,请执行以下步骤。

  1. 使用下列 值填充 ADS _ VLV 结构。 结构的其他成员应设置为零或 NULL

    • dwContentCount 成员设置为要检索的项的比率的最大值。
    • dwOffset 成员设置为要检索的项相对于 dwContentCount 的比率。
    • lpContextID 成员设置为上下文 ID 缓冲区副本的地址,将 dwContextIDLength 设置为上下文 ID 缓冲区的长度(以字节为单位)。 如果未保存上下文 ID,则这两个成员应为零或 NULL。
  2. 设置搜索首选项,如获取项数过程的步骤 2 到 5 所示。

  3. 使用 IDirectorySearch::ExecuteSearch 执行搜索

  4. 通过调用 IDirectorySearch::GetFirstRow 获取结果的第一行

  5. 使用 要检索的属性的名称调用 IDirectorySearch::GetColumn, 获取所请求项的实际数据。

  6. 使用 ADS _ VLV _ RESPONSE 调用 IDirectorySearch::GetColumn以获取 VLV 搜索元数据。

  7. ADS SEARCH COLUMN 结构的 pADsValues->ProviderSpecific.lpValue 强制转换到 ADS _ VLV结构指针。 _ _

  8. 创建 lpContextID 数据的副本,并保留该数据供下一个 VLV 搜索使用。

GetVLVItemText示例函数演示如何执行此操作。

也可通过单个搜索调用检索多行数据。 这是通过正确设置 ADS _ VLV结构的 dwBeforeCountdwAfterCount 成员在步骤 1 中完成。 dwBeforeCount 成员包含在有关项之前显示在列表中的项数 ,dwAfterCount 成员包含列表之后出现在有关项的项数。 这两个计数都排除项本身,因此将 dwBeforeCount 设置为 10,将 dwAfterCount 设置为 10 将导致总共返回 21 个项。 此选项允许缓存客户端上的搜索结果。

按字符串搜索

也可使用 VLV 搜索查找具有字符串属性的项,其值与字符串的一部分或全部匹配,而无需检索所有项。 字符串匹配针对 ADS _ SEARCHPREF _ SORT _ ON 搜索首选项 的 ADS _ SORTKEY结构中指定的属性执行。

若要按字符串搜索特定项,请执行以下步骤。

  1. 使用下列 值填充 ADS _ VLV 结构。 结构的其他成员应设置为零或 NULL

    • pszTarget 成员设置为指向以 NULL 结尾的字符串的指针,该字符串包含要搜索的字符串。
    • lpContextID 成员设置为上下文 ID 缓冲区副本的地址,将 dwContextIDLength 设置为上下文 ID 缓冲区的长度(以字节为单位)。 如果未保存上下文 ID,则这两个成员应为零或 NULL。
  2. 设置搜索首选项,如获取项数过程的步骤 2 到 5 所示。

  3. 使用 IDirectorySearch::ExecuteSearch 执行搜索

  4. 通过调用 IDirectorySearch::GetFirstRow 获取结果的第一行

  5. 使用 要检索的属性的名称调用 IDirectorySearch::GetColumn, 获取所请求项的实际数据。

  6. 使用 ADS _ VLV _ RESPONSE 调用 IDirectorySearch::GetColumn以获取 VLV 搜索元数据。

  7. ADS SEARCH COLUMN 结构的 pADsValues->ProviderSpecific.lpValue 强制转换到 ADS _ VLV结构指针。 _ _

  8. 创建 lpContextID 数据的副本,并保留该数据供下一个 VLV 搜索使用。 如果需要 ,dwOffset 成员包含其字符串属性以 pszTarget 中指定的值开头的第一个项的从一开始的索引。

GetVLVItemsByString示例函数演示如何执行此操作。

与按索引搜索类似,也可通过单个搜索调用检索多行数据。 这是通过正确设置 ADS _ VLV结构的 dwBeforeCountdwAfterCount 成员以相同的方式完成的。