Метод DigestSearch для баз данных Lotus DominoИсточник: IBM developerWorks Россия
В данной статье представляется DigestSearch, альтернативное решение для работы с документами IBM Lotus Notes Profile и для выполнения одиночных, высокоскоростных операций поиска. Для поиска в серверных базах данных из Notes-клиента DigestSearch в два раза быстрее любых других доступных методов поиска, превосходя по характеристикам как полнотекстовый поиск, так и метод LotusScript GetDocumentByKey. Метод DigestSearch лучше всего может быть описан как решение, альтернативное методу поиска LotusScript View.GetDocumentByKey для работы с документами Profile. Его главным предназначением является поиск одного или более документов с использованием одиночного поискового слова (например, номера карточки социального страхования (SSN), номера телефона) или поиск уникального порядкового номера сохраненной SQL-записи (Structured Query Language). Главным преимуществом DigestSearch является то, что для поиска в больших базах данных (особенно в серверных базах данных из Notes-клиента) он превосходит все другие традиционные методы по скорости. Фактически, в зависимости от сложности поиска, метод DigestSearch может быть в 20 раз быстрее! И DigestSearch не требует каких-либо представлений (view) для выполнения операций поиска, поэтому вы можете уменьшить размер вашей базы данных, удалив ненужные представления. Количество документов в вашей базе данных не сильно влияет на скорость операций поиска с DigestSearch. Главным недостатком DigestSearch является то, что он принимает только одно ключевое слово без групповых символов. В этом отношении метод похож на метод LotusScript View.GetDocumentByKey и на @DBLookup. То есть, если для вас важна производительность и поисковые слова предсказуемы, подумайте над использованием метода DigestSearch. Реализация DigestSearch в вашей базе данных не требует каких-либо значительных изменений дизайна или модификаций в существующих документах. Хотя в методе все еще есть место для улучшений (особенно в области индексации и поиска по нескольким ключевым словам), он может обеспечить существенное повышение производительности уже сегодня. Примеры баз данных, рассмотренные в данной статье (Digestprofile.nsf (база данных документов Profile), Testindex.nsf (база данных Demo Index), Digest2.nsf (DigestSearch для простых операций поиска) и Demonab.nsf (демонстрационный каталог Domino)), расположены в файле Digest_dbs.zip, который доступен для загрузки в разделе Download. В данной статье мы покажем два способа использования метода DigestSearch:
В данной статье предполагается, что вы являетесь опытным программистом на Notes/Domino. ПроизводительностьПри сравнении скорости поиска метода DigestSearch и традиционных методов поиска Domino, результаты которого показаны в следующих двух таблицах, вы можете увидеть, что при использовании одиночного ключевого слова для поиска одного документа, DigestSearch превосходит все другие методы, особенно если база данных размещена на сервере, и вы выполняете поиск из Notes-клиента. В нашем тесте производительности мы измеряли время, требующееся для получения описателя объекта для 100 документов. Мы измеряли результаты примера поиска в Domino Directory и эмулировали поиск, состоящий из нескольких этапов. Вы можете выполнить свой собственный тест, используя тестовый агент Performance в базе данных Digest Search 2 (Digest2.nsf). Примечание: Этот тест производительности не предназначался для общего сравнением скорости методов; результаты применимы только для конкретной задачи поиска членов группы. В первой таблице эмулируемые пользователи выполняли операцию поиска из Notes-клиента, а база данных размещалась на сервере:
Во второй таблице приведены результаты поиска из Notes-клиента в локальной базе данных:
Как можно увидеть, при локальной работе @DBLookup является вторым по скорости методом; но при работе с серверной базой данных он является предпоследним по скорости. Но на результаты мог повлиять возврат описателя документа вместо текста. Вторым интересным фактом является то, что Db.Search только на 30% медленнее при поиске на сервере, в то время как другие методы становятся медленнее как минимум в два раза. Примечание: В этом тесте мы использовали @DBLookup с параметром Cache и с несколькими ключевыми словами, скомбинированными в одном и том же запросе, что не всегда возможно для реальных операций поиска. Как работает DigestSearchМетод DigestSearch реализуется полностью на LotusScript. Его основной код занимает примерно 30 строк. Вы можете использовать DigestSearch для поиска в фоновом режиме, а его синтаксис и функциональность напоминают метод View.GetAllDocumentsByKey("searchword", True). Главное сходство между этими двумя методами состоит в том, что оба они принимают одно ключевое слово в качестве параметра и возвращают один или более совпадающих документов. Отличия состоят в том, что DigestSearch не требует представлений для выполнения поиска и всегда ищет точное совпадение с искомым словом. Метод DigestSearch вызывается при помощи следующей команды LotusScript:
Метод называется DigestSearch, потому что он использует значение уникального дайджеста (однонаправленная функция) для представления искомого слова. Этот уникальный ключ является закодированным искомым словом, представленным как строка из 32 символов, которая, в свою очередь, используется как Universal ID (UNID) для документа. Таким образом, DigestSearch на самом деле не выполняет поиск в базе данных; он просто проверяет, существует ли документ с конкретным UNID. Вот простой пример выполнения операции поиска. Если вы поймете, как работает алгоритм, будет легко его изменить и настроить:
В следующем коде показан упрощенный рабочий пример @formula для выполнения поиска по дайджесту:
А вот код агента LotusScript, используемый в предыдущем коде:
В фоновой библиотеке сценариев при работе этого агента выполняется следующий процесс: искомое слово преобразуется в дайджест при помощи метода @Password. Этот шаг формирует UNID-совместимую строку из 32 символов.
Библиотека проверяет, существует ли документ с этим UNID:
Примечание: Вы должны обработать возможные ошибки Invalid universal ID (Неверный универсальный ID), которые будут возникать, если для искомого дайджеста нет соответствующего документа. Если digestdoc не возвратил ошибку 4091 Invalid universal ID, сценарий передает описатель документа назад в вызывающую функцию:
Сценарий показывает значения из найденного документа пользователю:
Этот код показывает всю библиотеку DigestSearchLib LotusScript, содержащую ядро метода DigestSearch:
Использование DigestSearch для работы с документами ProfileВы, возможно, заметили, что Lotus Notes кэширует документы Profile. Такое поведение может быть проблемой, если два или более пользователей одновременно изменяют документ Profile. Из-за проблем кэширования пользователи получают устаревшие значения. Но вы можете решить эту проблему, используя метод DigestSearch вместо стандартной функциональности GetProfileDocument, как показано в следующем фрагменте кода:
Вы можете даже использовать язык формул для доступа к новым документам Profile с дайджестом, как показано в следующем коде:
К сожалению, вы не можете создать новый документы Profile с дайджестом, используя язык Notes @formula. Вы можете только искать существующие документы и изменять их (используя @SetDocField). В разделе Download данной статьи приведена ссылка на ZIP-файл, включающий базу данных "DigestSearch demo for profile docs" (Digestprofile.nsf), которая содержит исходный код агента "Modify example with Formula" и примеры. Эта база данных содержит также оба кода LotusScript и @formula для тестирования (см. рисунок 1). Нажмите кнопку "Create profile doc" в виде Instructions для создания нового профиля, а затем нажмите кнопку "Find profile doc" для поиска только что созданного вами профиля. Рисунок 1. Кнопки действия для тестирования профиля Использование DigestSearch для работы с простыми операциями поискаРабота с операциями поиска сложнее работы с документами Profile. Число документов Profile часто ограничено; они создаются по требованию и не зависят от других документов. Ситуация меняется, когда вы выполняете поиск в базе данных, содержащей сотни тысяч документов, которые связаны друг с другом и с другими базами данных. Для поддержания целостности существующих баз данных вы не можете менять UNID документов в этих базах данных напрямую. Следовательно, вам необходима специальная база данных mirror/index, в которой хранятся индексные документы для документов в родительской базе данных. Для базы данных индексов не нужно какое-либо проектирование; она просто содержит два типа документов:
Один документ-контейнер ссылки (форма SourceRefHolder) существует для каждого индексированного документа в исходной базе данных. Этот документ-контейнер ссылки содержит два динамически создаваемых поля: SKey и REFUNIDs. Поле SKey используется только как напоминание UNID оригинального документа в исходной базе данных; оно не используется для поиска. Поле REFUNIDs является многозначным полем, которое используется для хранения последовательности документов-контейнеров ключевого слова. То есть, поле содержит значения UNID документов-контейнеров ключевого слова. Количество документов-контейнеров ключевых слов для исходного документа равно количеству полей поиска каждого документа. Эти поля указываются в документе Configuration, как показано на рисунке 2. Каждый индексный документ тоже имеет многозначное поле UNIDs, которое содержит значение UNID всех документов исходной базы данных, соответствующих ключевому слову, присвоенному этому индексному документу. Рисунок 2. Документ Configuration Исходный код операции поиска аналогичен примеру с документом Profile, описанному ранее. Отличия таковы:
Предполагая, что база данных Demo Index обновлена и содержит все документы из исходной базы данных (то есть, Domino Directory), операция поиска выдает те же результаты, что и при поиске в исходной базе данных. Существует три основных способа обновления базы данных Demo Index новыми документами:
Примечание: База данных Digest Search 2 (Digest2.nsf) содержит агент под названием Process database index, который создает индекс для документов из исходной базы данных. Пример поиска в Domino DirectoryВ пример базы данных Digest Search 2 включены два агента, выполняющие поиск в Domino Directory. Один агент (Find users by first name) ищет все документы Domino Directory, в которых имя человека совпадает с введенным именем в поле вода. Второй агент (Find group members) ищет все документы Person для людей указанной группы. Для запуска примеров агентов вам необходимы три базы данных, показанные на рисунке 3:
Рисунок 3. Базы данных для примеров агентов Все три эти базы данных содержатся в ZIP-файле, ссылка на который приведена в разделе Download данной статьи. В базе данных Digest Search 2 вы должны настроить месторасположение баз данных Demo NAB и Demo Index, как показано на рисунках 2 и 4. После настройки путей к этим базам данных вы должны заполнить базу данных индексов информацией из Demo NAB. Для этого нажмите кнопку Synchronize Index в виде Configuration (см. рисунок 4). Рисунок 4. Кнопки действия в виде Configuration После завершения индексации вы можете выполнить операцию поиска. Просто нажмите "Find persons by first name" или "Find all users in a group". Затем введите имя пользователя или название группы и нажмите кнопку OK. В нашем примере в качестве имени пользователя используется John. Вы могли бы изменить его на соответствующее имя, существующее в вашем каталоге (см. рисунок 5). Если все настроено правильно, появится окно, аналогичное показанному на рисунке 6. Рисунок 6. Результаты поиска по имени При нажатии "Find all users in a group" в фоновом режиме происходят следующие события:
Когда использовать (а когда нет) DigestSearchИспользуйте DigestSearch тогда, когда вам требуется быстро найти один или более документов по одному ключевому слову. Документы Profile и документы для временного хранения данных являются наиболее очевидными областями применения. Аналогично, используйте DigestSearch тогда, когда по каким-либо причинам вы не можете применить традиционные методы поиска, но необходим высокопроизводительный поиск (предпочтительно, для статических данных, например в Domino Directory). Вот практические примеры ситуаций, когда вы должны подумать об использовании DigestSearch:
Вот практические примеры ситуаций, когда не нужно использовать DigestSearch:
Метод DigestSearch первоначально был создан для повышения скорости синхронизации большого количества SQL-записей с базой данных Domino. Каждая SQL-запись имеет свой собственный Unique Sequence Number, и вы можете вычислить также индивидуальный уникальный номер для всех комбинированных полей в записи. Каждая запись существует только в одном экземпляре, что делает их отличным объектом для применения метода DigestSearch. Вы можете избежать кэширования существующих документов (в нашем случае было более 1000000 документов) в массиве или в списке, и время синхронизации может быть уменьшено с 25 минут до 10 минут. Что нужно сделать в следующей версии DigestSearchКак упоминалось ранее, в методе DigestSearch есть место для улучшений. Некоторые проблемы легко преодолеть, тогда как для других необходимы новые подходы. Вот некоторые изменения, которые мы хотели бы увидеть в будущих версиях метода DigestSearch:
Скорость имеет значениеВ нормальных условиях DigestSearch выдает результаты быстрее, чем традиционные методы поиска. Если вам не нужны богатые возможности развитых запросов, предлагаемые FTSearch и DBSearch, но вы ищете альтернативу методу GetDocumentByKey или @DBLookup для документов Profile, загрузите примеры баз данных и посмотрите, полезен ли будет вам метод DigestSearch. С помощью примеров, включенных в эту статью, и примеров баз данных, вы можете протестировать функциональность метода DigestSearch в течение минут и реализовать его для ваших собственных приложений, просто изменив документ Configuration. |