Метод DigestSearch для баз даних Lotus Domino, Інші СУБД, Бази даних, статті

В даній статті представляється 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-клієнта, а база даних розміщувалася на сервері:






















Метод пошуку  Час в секундах 
DigestSearch 2.9
Db.Search 13.1
Db.FTSearch 6.1
View.GetDocumentByKey 5.8
@DBLookup 12.1

У другій таблиці наведені результати пошуку з Notes-клієнта в локальній базі даних:






















Метод пошуку  Час в секундах 
DigestSearch 1.2
Db.Search 9.7
Db.FTSearch 2.8
View.GetDocumentByKey 0.9
@DBLookup 1.2

Як можна побачити, при локальній роботі @ DBLookup є другим за швидкістю методом; але при роботі з серверної базою даних він є передостаннім за швидкістю. Але на результати міг вплинути повернення описувача документа замість тексту. Другим цікавим фактом є те, що Db.Search тільки на 30% повільніше при пошуку на сервері, в той час як інші методи стають повільніше як мінімум в два рази.


Примітка: У цьому тесті ми використовували @ DBLookup з параметром Cache і з декількома ключовими словами, скомбіновані в одному і тому ж запиті, що не завжди можливо для реальних операцій пошуку.


Як працює DigestSearch


Метод DigestSearch реалізується повністю на LotusScript. Його основний код займає приблизно 30 рядків. Ви можете використовувати DigestSearch для пошуку у фоновому режимі, а його синтаксис і функціональність нагадують метод View.GetAllDocumentsByKey (“searchword”, True). Головне подібність між цими двома методами полягає в тому, що обидва вони приймають одне ключове слово в якості параметра і повертає один або більше співпадаючих документів. Відмінності полягають у тому, що DigestSearch не вимагає уявлень для виконання пошуку і завжди шукає точний збіг з шуканим словом.


Метод DigestSearch викликається за допомогою наступної команди LotusScript:


Set doc=FastSearchByKey(db, “searchword”)

Метод називається DigestSearch, тому що він використовує значення унікального дайджесту (односпрямована функція) для подання шуканого слова. Цей унікальний ключ є закодованим шуканим словом, представленим як рядок з 32 символів, яка, в свою чергу, використовується як Universal ID (UNID) для документа. Таким чином, DigestSearch насправді не виконує пошук в базі даних; він просто перевіряє, чи існує документ з конкретним UNID.


Ось простий приклад виконання операції пошуку. Якщо ви зрозумієте, як працює алгоритм, буде легко його змінити і налаштувати:


  1. Користувач шукає номер телефону +1 212 12345678, для того щоб знайти ім’я його власника.
  2. +1 212 12345678 перетвориться в дайджест за допомогою функції @ Password. Результат – рядок дайджесту / хеша 3F915F67F52D35053113AAB40385FE46.
  3. Сценарій перевіряє, чи існує в базі даних документ з UNID 3F915F67F52D35053113AAB40385FE46.
  4. Якщо документ знайдений, пошук завершується. Сценарій зчитує поля з документа й відображає їх користувачеві, або просто відкриває документ в інтерфейсі. Якщо документ не знайдено, користувач бачить повідомлення про те, що документ з таким ключовим словом не існує.

У наступному коді показаний спрощений робочий приклад @ formula для виконання пошуку по дайджесту:






seachrword:=”+1 212 12345678″;
fullname:=@GetDocField(@Middle(@Password(seachword);1;32);
“FullName”);@Prompt([Ok];”Result for “+searchword;
@If(@IsError(fullname);”Document “+searchword+” does not exist”;
“Fullname: “+fullname))

А ось код агента LotusScript, використовуваний в попередньому коді:






Option Public
Use “DigestSearchLib”
Sub Initialize
Dim session as New NotesSession
Dim db As NotesDatabase
Dim doc As NotesDocument, curdoc as NotesDocument
Dim workspace As New NotesUIWorkspace
Dim uidoc As NotesUIDocument
Dim searchstring As String
Set uidoc = workspace.CurrentDocument
Set curdoc=uidoc.CurrentDocument
Set db=session.CurrentDatabase
searchstring = doc.inputfield (0) “Введення номера телефону у форму “Вийти, якщо номер телефону не вказано
If searchstring = “” Then Exit Sub
Set doc= FastSearchByKey(db, searchstring) ” Perform DigestSeach and “Повернути описувач документа
If Not doc Is Nothing Then
curdoc.FullName=doc.FirstName(0)+” “+doc.LastName(0) “Заповнити поля поточного документа інформацією “З знайденого документа
curdoc.Address=doc.Address(0)
curdoc.Job=doc.JobDescription(0)
Else “Документ не знайдено, проінформувати про це користувача
Msgbox “Info for “+searchtxt+” not found”
End If
End Sub

В фонової бібліотеці сценаріїв при роботі цього агента виконується наступний процес: шукане слово перетворюється в дайджест за допомогою методу @ Password. Цей крок формує UNID-сумісну рядок з 32 символів.


ev=Evaluate(/@Password(“/+skey+/”)/)

Бібліотека перевіряє, чи існує документ з цим UNID:


On Error 4091 Goto wrongiderr4091 Set digestdoc= digestdb.GetDocumentByUNID(Mid(ev(0),2,32))

Примітка: Ви повинні обробити можливі помилки Invalid universal ID (Невірний універсальний ID), які будуть виникати, якщо для шуканого дайджесту немає відповідного документа.


Якщо digestdoc не повернув помилку 4091 Invalid universal ID, сценарій передає описувач документа назад в зухвалу функцію:






Set FindDocByDigestKey=digestdoc
Exit Function
wrongiderr4091:
Set FindDocByDigestKey=Nothing

Сценарій показує значення з знайденого документа користувачеві:


curdoc.FullName=doc.FirstName(0)+” “+doc.LastName(0)

Цей код показує всю бібліотеку DigestSearchLib LotusScript, що містить ядро ​​методу DigestSearch:






“—- Початок бібліотеки сценаріїв DigestSearchLib ——
Dim digestdb As NotesDatabase
Dim digestdoc As NotesDocument
Dim lastkey As String
Dim lastgeneratedID As String
Dim lastgeneratedDoc As NotesDocument
Function FindDocByDigestKey(custdb As NotesDatabase,skey As String)_ As NotesDocument “це головна функція для отримання результатів пошуку
Dim unid As String
Set digestdb=custdb
On Error Goto errh
unid=CalculateDigest(skey)
If Len(unid)<>32 Then
Set FindDocByDigestKey=Nothing
Exit Function
End If
Set digestdoc = lastgeneratedDoc “LastgeneratedDoc є глобальною змінною “Повернення описувача документа викликає агенту
Set FindDocByDigestKey=digestdoc
Set digestdoc=Nothing
Exit Function
errh: Set FindDocByDigestKey = Nothing “для цього ключового слова документи не знайдені
Resume endas
endas:
End Function
Function IsDigestKeyTaken(unid As String) “Ця функція перевіряє, чи існує документ для ключового слова
On Error Resume Next “Помилка 4091 означає невірний Universal ID
On Error 4091 Goto wrongiderr4091 “Перевіряє, чи існує вже документ з унікальним ключовим словом
Set digestdoc= digestdb.GetDocumentByUNID(unid) IsDigestKeyTaken=True
Set lastgeneratedDoc=digestdoc
Exit Function
wrongiderr4091:
IsDigestKeyTaken=False
Resume wrongID
wrongID:
End Function
Function CalculateDigest(skey As String) “Ця функція обчислює 32-символьний дайджест для ключового слова
Dim unid As String “Вирахувати дайджест для ключового слова
ev=Evaluate(/@Password(“/+skey+/”)/) unid = Mid (ev (0), 2,32) “видалити круглі дужки навколо згенерованого дайджесту lastgeneratedID = unid “присвоїти глобальної змінної нове значення
If IsDigestKeyTaken(unid)=False Then
unid=”no doc with that digest yet”
End If
CalculateDigest=unid
End Function
Sub MakeSearchable(sdoc As NotesDocument) “Ця функція встановлює новий Universal ID і зберігає документ
unid=lastgeneratedID
sdoc.UniversalID=unid
End Sub “—– Кінець бібліотеки сценаріїв ——

Використання DigestSearch для роботи з документами Profile


Ви, можливо, помітили, що Lotus Notes кешує документи Profile. Така поведінка може бути проблемою, якщо два або більше користувачів одночасно змінюють документ Profile. Через проблеми кешування користувачі отримують застарілі значення. Але ви можете вирішити цю проблему, використовуючи метод DigestSearch замість стандартної функціональності GetProfileDocument, як показано в наступному фрагменті коду:






Set db=session.CurrentDatabase “Виконати пошук і повернути описувач документа
Set profiledoc = FastSearchByKey(db, “My Profile 1”)
If Not profiledoc Is Nothing Then MsgBox profiledoc.Field1 (0) “показати поле з документа профілю profiledoc.Field2 = Cstr (Now) “оновити профіль новим значенням поля Call profiledoc.save (True, False) “зберегти документ профілю
End If

Ви можете навіть використовувати мову формул для доступу до нових документів Profile з дайджестом, як показано в наступному коді:






profname:=”My Profile 1″;
comment:=@GetDocField(@Middle(@Password(profname);1;32); “comment”);
createddate:=
@GetDocField(@Middle(@Password(profname);1;32); “doccreated”);
@Prompt([Ok];”Result for “+profname; @If(@IsError(comment);
“Profile “+profname+”does not exist”;
“Comment: “+comment+@Char(10)+”Created: “+createddate))

На жаль, ви не можете створити новий документи 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
Action buttons in Configuration view

Після завершення індексації ви можете виконати операцію пошуку. Просто натисніть “Find persons by first name» або «Find all users in a group”. Потім введіть ім’я користувача або назва групи і натисніть кнопку OK. У нашому прикладі в якості імені користувача використовується John. Ви могли б змінити його на відповідне ім’я, що існує у вашому каталозі (див. малюнок 5).


Рисунок 5. Пошук по імені

Якщо все налаштовано правильно, з’явиться вікно, аналогічне показаному на малюнку 6.


Малюнок 6. Результати пошуку по імені

При натисканні “Find all users in a group” у фоновому режимі відбуваються наступні події:


  1. Сценарій ідентифікує відповідний індексний документ (тобто, документ-контейнер ключового слова) для ключового слова listname = demogroup.
  2. У цьому індексному документі сценарій ідентифікує UNID вихідного документа у вихідній базі даних.
  3. Сценарій зчитує поле Members з вихідного документа і для кожної людини з цього поля сценарій виконує нову операцію пошуку з новим сформованим ключовим словом “fullname =” + doc.members (x).
  4. Операція пошуку повторюється до тих пір, поки не обробити всі люди в списку, а потім у текстовому рядку формується відповідь.
  5. MessageBox відображає користувачеві отриману текстову рядок.

Коли використовувати (а коли немає) 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.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*