Поделиться через


Поиск с помощью VLV

Active Directory поддерживает поиск с использованием виртуального представления списков (VLV). Этот стиль поиска специально предназначен для больших результирующих наборов и позволяет приложению отображать подмножество тысяч записей без фактического получения каждой записи.

Существует два разных способа использования поиска VLV. Первое — получить атрибуты для определенных записей на основе числового смещения. Этот метод полезен при получении результатов поиска в ответ на операцию прокрутки.

Вторым способом использования поиска VLV является поиск части или всего текстового атрибута и отображение результатов поиска. Примером использования этого является адресная книга. Если пользователь вводит "s", приложение может использовать поиск VLV для поиска записей с общим именем, начинающимся с "s". Если пользователь добавляет "m" в "s", приложение может использовать другой поиск VLV для поиска записей с общим именем, начинающимся с "sm".

Чтобы выполнить поиск VLV, попросите ADSI использовать элемент управления VLV. Для этого вызовите метод IDirectorySearch::SetSearchPreference с параметром поиска ADS_SEARCHPREF_VLV со значением ADSTYPE_PROV_SPECIFIC. Значение ADSTYPE_PROV_SPECIFIC — это указатель на структуру ADS_VLV, содержащую данные о поиске. В примере функции GetVLVItemCountпоказано, как задать оба этих параметра поиска.

Все поиски VLV должны использовать сортировку результатов на стороне сервера, задавая предпочтение поиска ADS_SEARCHPREF_SORT_ON. Дополнительные сведения о предпочтениях поиска ADS_SEARCHPREF_SORT_ON см. в разделе Сортировка результатов поиска с помощью IDirectorySearch.

При выполнении поиска VLV определенный объем метаданных о поиске возвращается в столбце, который извлекается путем вызова IDirectorySearch::GetColumn с идентификатором ADS_VLV_RESPONSE. Эти данные содержатся в структуре ADS_VLV. Особое значение имеют члены dwContentCount и lpContextID. Элемент dwContentCount будет содержать количество результатов, соответствующих критериям поиска VLV. Это значение можно использовать в качестве оценки общего количества элементов, возвращаемых для поиска этого типа. Элемент lpContextID содержит определяемое сервером значение, которое можно передать в следующий поиск для идентификации поиска. Использование lpContextID может повысить производительность поиска. Помните, что lpContextID является серверным значением, а его длина содержится в элементе dwContextIDLength. Этот буфер освобождается при вызове метода IDirectorySearch::FreeColumn, поэтому вызывающий объект должен выделить буфер соответствующего размера и скопировать и сохранить содержимое буфера между поиском.

Дополнительные сведения об элементе управления LDAP VLV см. в разделе Поиск с помощью элемента управления LDAP VLV.

Дополнительные сведения см. в следующем разделе:

Получение количества элементов

Чтобы получить оценку количества элементов, которые будут возвращены для определенного поиска, выполните следующие действия.

  1. Заполните структуру ADS_VLV всеми нулевыми или значениями NULL.

  2. Заполните ADS_SEARCHPREF_INFO следующими значениями.

    • Задайте для элемента dwSearchPref значение ADS_SEARCHPREF_VLV.
    • Задайте для члена vValue.dwType значение ADSTYPE_PROV_SPECIFIC.
    • Задайте для элемента vValue.ProviderSpecific.dwLength размер структуры ADS_VLV.
    • Установите для элемента vValue.ProviderSpecific.lpValue адрес структуры ADS_VLV из Шага 1.
  3. Заполните структуру ADS_SORTKEY, как показано в разделе "Сортировка результатов поиска с использованием IDirectorySearch", чтобы сортировать по нужному атрибуту.

  4. Заполните еще один ADS_SEARCHPREF_INFO, чтобы добавить структуру ADS_SORTKEY в параметры поиска, как показано в сортировке результатов поиска с помощью IDirectorySearch.

  5. Добавьте любые другие нужные параметры поиска и вызовите IDirectorySearch::SetSearchPreference, чтобы задать параметры поиска.

  6. Выполните поиск с помощью IDirectorySearch::ExecuteSearch.

  7. Получите первую строку результатов, вызвав IDirectorySearch::GetFirstRow.

  8. Вызовите IDirectorySearch::GetColumn с ADS_VLV_RESPONSE, чтобы получить метаданные поиска VLV.

  9. Приведение pADsValues->ProviderSpecific.lpValue структуры ADS_SEARCH_COLUMN к указателю структуры ADS_VLV. Элемент dwContentCount этой структуры ADS_VLV содержит приблизительное количество элементов, возвращаемых поиском этого типа.

  10. Если другие поиски VLV одного типа будут выполнены, скопируйте данные lpContextID и сохраните его для следующего поиска VLV.

Пример функции GetVLVItemCountпоказывает, как это сделать.

Поиск по смещениям

Одним из факторов, делающих поиски с помощью VLV такими быстрыми, является возможность искать определенный результат по числовому смещению. Например, если поиск вернет 10 000 элементов, поиск VLV позволяет получить сведения примерно о 4072-м элементе без необходимости извлекать все элементы перед ним.

Смещения указываются в качестве соотношения между смещением и количеством содержимого. Коэффициенты полезны, так как сервер может не иметь точной оценки количества записей, существующих в списке, или размер списка может меняться в течение времени, когда пользователь просматривает его. Так как необходимо указать начало и конец списка, можно использовать предполагаемое значение для количества содержимого в первом запросе поиска, а также значение смещения. Сервер использует эти данные для вычисления соответствующих смещения в списке на основе его идеи количества содержимого, который отправляется в ответ на клиент через элемент dwContentCount dwContentCount член структуры ADS_VLV. Например, если вы оцениваете размер списка равным 3000, а смещение должно быть в списке 1500, то присвойте dwContentCount значение 3000 и dwOffset значение 1500. Если сервер оценивает фактический размер списка 4500, он перерасчитывает смещение до 2250 и возвращает новые оценки в dwContentCount и dwOffset.

Заметка

Все числовые значения в поиске VLV являются приблизителями и не должны использоваться для абсолютных значений. Например, если вы запускаете VLV-запрос на 50-й элемент из 100, вам не гарантируется получение точно среднего элемента.

Для поиска определенного элемента по смещением выполните следующие действия.

  1. Заполните структуру ADS_VLV следующими значениями. Дополнительные элементы структуры должны иметь значение нулю или NULL.

    • Задайте для элемента dwContentCount максимальное значение коэффициента извлекаемых элементов.
    • Задайте элементу dwOffset отношение относительно dwContentCountэлемента или элементов для извлечения.
    • Задайте элементу lpContextID адрес копии буфера идентификатора контекста и dwContextIDLength длину буфера идентификатора контекста в байтах. Если идентификатор контекста не сохранен, оба этих элемента должны быть равны нулю или null.
  2. Задайте параметры поиска, как описано в шагах 2–5 процедуры получения количества элементов.

  3. Выполните поиск с помощью IDirectorySearch::ExecuteSearch.

  4. Получите первую строку результатов, вызвав IDirectorySearch::GetFirstRow.

  5. Выполните вызов IDirectorySearch::GetColumn, указав имя атрибута, чтобы получить фактические данные запрошенного элемента.

  6. Вызовите IDirectorySearch::GetColumn с ADS_VLV_RESPONSE, чтобы получить метаданные поиска VLV.

  7. Приведение pADsValues->ProviderSpecific.lpValue структуры ADS_SEARCH_COLUMN к указателю структуры ADS_VLV.

  8. Создайте копию данных lpContextID и сохраните ее для следующего поиска VLV.

 

Пример функции GetVLVItemTextпоказывает, как это сделать.

Кроме того, можно получить несколько строк данных с одним вызовом поиска. Это делается на шаге 1 путем задания dwBeforeCount и dwAfterCount членов структуры ADS_VLV соответствующим образом. Элемент dwBeforeCount содержит количество элементов, которые отображаются в списке до указанного элемента, и элемент dwAfterCount dwAfterCount содержит количество элементов, которые отображаются в списке после того, как этот элемент будет указан в вопросе. Оба этих счетчика исключают сам элемент, поэтому при установке значения dwBeforeCount равным 10 и dwAfterCount равным 10 возвращается в общей сложности 21 элемент. Этот параметр позволяет кэширование результатов поиска на стороне клиента.

Поиск по строке

Также можно использовать поиск VLV для поиска элементов, имеющих строковый атрибут, значение которого соответствует всем или части строки без необходимости извлекать все элементы. Сопоставление строк выполняется по атрибуту, указанному в структуре ADS_SORTKEY параметра сортировки поиска ADS_SEARCHPREF_SORT_ON.

Чтобы выполнить поиск определенного элемента по строке, выполните следующие действия.

  1. Заполните структуру ADS_VLV следующими значениями. Дополнительные элементы структуры должны быть равны нулю или NULL.

    • Задайте элементу pszTarget указатель на строку, завершающую значение NULL, содержащую строку для поиска.
    • Задайте элементу lpContextID адрес копии буфера идентификатора контекста и dwContextIDLength длину буфера идентификатора контекста в байтах. Если идентификатор контекста не сохранен, оба этих элемента должны быть равны нулю или null.
  2. Задайте параметры поиска так, как показано в шагах 2 по 5 из процедуры получения количества элементов.

  3. Выполните поиск с помощью IDirectorySearch::ExecuteSearch.

  4. Получите первую строку результатов, вызвав IDirectorySearch::GetFirstRow.

  5. Вызовите IDirectorySearch::GetColumn, используя имя атрибута, чтобы получить фактические данные для запрошенного элемента.

  6. Вызовите IDirectorySearch::GetColumn с использованием ADS_VLV_RESPONSE, чтобы извлечь метаданные поиска VLV.

  7. Приведение pADsValues->ProviderSpecific.lpValue структуры ADS_SEARCH_COLUMN к указателю структуры ADS_VLV.

  8. Создайте копию данных lpContextID и сохраните ее для следующего поиска VLV. При необходимости элемент dwOffset содержит одноуровневый индекс первого элемента, строковый атрибут которого начинается со значения, указанного в pszTarget.

В примере функции GetVLVItemsByString показано, как это сделать.

Аналогично поиску по индексу, также можно получить несколько строк данных с одним вызовом поиска. Это достигается таким же образом, задав dwBeforeCount и dwAfterCount членов структуры ADS_VLV соответствующим образом.