|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
DigestSearchメソッドによるLotus Dominoデータベースの検索 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Andrei Kouvchinnikov, Principal Domino Developer, Botstation レベル:初級 原文の掲載:2006年01月31日 更新日:2006年10月06日更新
DigestSearchメソッドを一言で表現すれば、プロフィール文書を用いた検索での、LotusScriptのView.GetDocumentByKeyメソッドにかわる方法といえます。DigestSearchの主な目的は、1つの検索語を使用して1つ以上の文書を見つけることです。たとえば、社会保障番号、電話番号、Structured Query Language(SQL)レコードに格納されている固有のシーケンス番号などを使用した検索です。 DigestSearchの最大の利点は、大きなデータベースの検索で(特に、Lotus Notes Clientからサーバー・ベースのデータベースを検索する場合)、従来からのどの方法よりも、検索スピードが優れていることです。実際に、検索の複雑さにもよりますが、DigestSearchによる方法では最大で20倍も速くなります。また、DigestSearchは検索を実行するためにビューをまったく必要としないため、不要なビューを削除することによってデータベースのサイズを削減できます。DigestSearchによる検索では、データベースの文書数が実質的に検索速度に影響することはありません。 DigestSearchの短所は、ワイルドカードでないキーワードを1つしか受け取れないことです。この点で、この方法はLotusScriptのView.GetDocumentByKeyメソッドと@DBLookupに似ています。このため、パフォーマンスが重要で検索キーワードが予測可能な場合に、DigestSearchメソッドの使用を検討するとよいでしょう。DigestSearchをデータベースに実装する際は、大きな設計の変更や既存の文書への変更は不要です。この方法は、まだ改良の余地がありますが(特に、索引作成と複数キーワードでの検索に関し)、現在でも、非常に優れたパフォーマンスを提供します。 この記事で使用するサンプル・データベースのDigestprofile.nsf(プロフィール文書データベース)、Testindex.nsf(デモ用の索引データベース)、Digest2.nsf(簡単な検索用のDigestSearch)、およびDemonab.nsf(デモ用のDominoディレクトリ)は、Digest_dbs.zipファイルに収録されています。このファイルは、「ダウンロード」セクションからダウンロードして利用できます。 この記事では、DigestSearchメソッドを使用できる2つの方法を紹介します。
この記事は、Lotus Notes/Dominoのプログラミングの経験がある方を対象として書かれています。 パフォーマンスDigestSearchによる方法とLotus Dominoの従来の検索方法の検索速度を比較すると、次の2つの表に示すように、単一キーワードを使用した単一文書の検索では、DigestSearchの速度が他のすべての方法を上回っています。特に、データベースがサーバー上にあり、Lotus Notes Clientから検索を実行した場合に、良いパフォーマンスを得られます。このパフォーマンス・テストでは、100文書へのオブジェクト・ハンドルを取得するのに必要な時間を測定しました。測定は、Dominoディレクトリの検索サンプルで複数のステップで構成される検索をシミュレートした結果に対して行いました。[Digest Search 2]データベース(Digest2.nsf)に含まれる[Performance test]エージェントを使用することにより、このテストをご自分で実行できます。 メモ:このパフォーマンス・テストは、検索方法間での汎用の速度比較のためには設計されていません。結果は、グループのメンバーを検索する特定のタスクにのみ適用できます。 最初の表は、ユーザーがLotus Notes Clientからサーバー上のデータベースに検索を実行するようすをシミュレートしたものです。
2番目の表は、Lotus Notes Clientからローカル・データベースに検索を実行したときの結果を示します。
表からわかるように、@DBLookupをローカルで実行すると、2番目に速い方法になりますが、サーバー・ベースのデータベースに実行すると、2番目に遅い方法となります。(純粋なテキスト結果の代わりに文書ハンドルを返したため、結果に影響した可能性があります。)また、他の方法はサーバー上では少なくとも2倍遅くなっているのに対し、Db.Searchは30%しか遅くなっていない点も興味深い事実です。 メモ:このテストでは、Cacheパラメーターをオンにして@DBLookupを使用し、複数のキーワードを同じ検索に組み込みました。実際の検索では、常にこの方法が可能であるとは限りません。
DigestSearchはどのように機能するのかDigestSearchメソッドはLotusScriptに完全に実装できます。この手法のコア・コードは約30行です。DigestSearchはバックグラウンド検索で使用でき、その構文と機能はView.GetAllDocumentsByKey("searchword",True)メソッドに似ています。この2つの方法で最も似ているのは、どちらも1つのキーワードをパラメーターとして受け取り、一致する1つ以上の文書を結果として返す点です。違いとしては、DigestSearchは検索の実行にビューを必要とせず、検索語に完全に一致するものを常に検索します。 DigestSearchは、次のLotusScriptコマンドを使用して呼び出します。 この方法は、固有のダイジェスト(不可逆ハッシュ)値を使用して検索語を表すので、DigestSearchと呼ばれています。固有キーは、暗号化された検索語で、32文字のストリングになります。これは、文書のUniversal ID(UNID)として使用されます。つまり、DigestSearchは実際にはデータベースを検索せず、特定のUNIDを持つ文書が存在するかどうかを単にチェックしています。 検索フローの簡単な例を示します。検索フローがどのように機能するかを理解することで、変更やカスタマイズが容易になります。
次のコードは、ダイジェスト検索を実行する簡単な@式の例です。
前の式で使用されるLotusScriptエージェントのコードは次のとおりです。
このエージェントが実行されるときに、バックグラウンドのスクリプト・ライブラリーでは次のプロセスが発生します。@Passwordによる方法を使用して、検索語がダイジェストに変換されます。(この手順では、UNIDと互換性がある32文字のストリングが生成されます。) ev=Evaluate(|@Password("|+skey+|")|) ev=Evaluate(|@Password("|+skey+|")|)
ライブラリーは、このUNIDを持つ文書が存在するかどうかをチェックします。 On Error 4091 Goto wrongiderr4091
Set digestdoc= digestdb.GetDocumentByUNID(Mid(ev(0),2,32))
メモ:検索ダイジェストに一致する文書がない場合に発生する可能性がある「Invalid universal ID」エラーを処理する必要があります。 digestdocの結果がエラー「4091 Invalid universal ID」にならなかった場合、スクリプトは文書のハンドルを呼び出し側の関数に返します。
スクリプトは、見つかった文書の値をユーザーに表示します。 curdoc.FullName=doc.FirstName(0)+" "+doc.LastName(0)
LotusScriptライブラリーのDigestSearchLibの全体のコードは次のとおりです。DigestSearchメソッドの中心となるコードが含まれています。
DigestSearchをプロフィール文書と共に使用するLotus Notesはプロフィール文書をキャッシュに保管します。この動作は、複数のユーザーが同時にプロフィール文書を変更すると、問題を引き起こす可能性があります。キャッシュの問題により、ユーザーは古い、期限切れとなった値を取得します。しかし、標準のGetProfileDocument機能の代わりにDigestSearchを使用することにより、この問題を解決できます。コードの一部を以下に示します。
次のコードのように、式言語を使用することによっても、新しいダイジェスト・プロフィール文書にアクセスできます。
残念ながら、Lotus Notesの@式言語を使用して新しいダイジェスト・プロフィール文書を作成することはできません。既存文書の検索と変更だけが可能です(@SetDocFieldを使用します)。この記事の「ダウンロード」セクションには、[DigestSearch demo for profile docs]データベース(Digestprofile.nsf)を含むZIPファイルがあります。このデータベースには、[Modify example with Formula]エージェントのソース・コードとサンプルが含まれています。また、このデータベースには、テスト用のLotusScriptと@式の両方のコードが含まれています(図1参照)。[Instructions]ビューで[Create profile doc]をクリックすると、新しいプロフィールが作成され、[Find profile doc]をクリックすると、作成したプロフィールを検索できます。 図1.プロフィールのテスト用のアクション・ボタン![]()
DigestSearchを単純な検索で使用する検索で使用する方が、プロフィール文書と共に使用するよりも複雑になります。プロフィール文書の数が制限されることがあります。プロフィール文書はオンデマンドで作成され、他の文書に依存しません。相互にリンクされていたり、他のデータベースとリンクしている数十万もの文書が含まれるデータベースの検索では、このようなケースはありません。 既存のデータベースの整合性を維持するために、これらのデータベース内で文書のUNIDを直接変更することはできません。このため、親データベース内の文書に対応する索引文書を維持する特殊なミラー/索引用のデータベースが必要です。 索引データベースには設計要素が不要で、単に次の2種類の文書が含まれています。
ソース・データベース内の各索引文書ごとに、1つの参照ホルダー文書(SourceRefHolderフォーム)が存在します。この参照ホルダー文書には、動的に作成される2つのフィールドSKeyとREFUNIDsがあります。SKeyフィールドは、検索用でなく、ソース・データベース内のオリジナル文書のUNIDの確認用としてのみ使用します。REFUNIDsフィールドは複数値フィールドで、キーワード・ホルダー文書をトラッキングするために使用します。つまり、このフィールドには、キーワード・ホルダー文書のUNIDが格納されます。 ソース文書あたりのキーワード・ホルダー文書の数は、各文書にある検索フィールドの数と同じです。これらのフィールドは、設定文書で指定します(図2参照)。それぞれの索引文書には、複数値フィールドのUNIDsがあり、このフィールドには、その索引文書に割り当てられたキーワードに一致するソース・データベース内のすべての文書のUNIDが格納されます。 図2.設定文書![]() 検索のソース・コードは、前に説明したプロフィール文書の例と似ています。違いは次のとおりです。
[Demo Index]データベースが更新されていて、このデータベースにソース・データベース(Dominoディレクトリ)からのすべての文書が含まれているものとすると、検索の結果は、ソース・データベースを検索したときと同じになります。 新しい文書で[Demo Index]データベースを更新するには、次の3つの方法があります。
メモ:[Digest Search2]データベース(Digest2.nsf)には、ソース・データベースの文書の索引を作成する[Process database index]エージェントが含まれています。
Dominoディレクトリの検索のサンプルサンプルの[Digest Search2]データベースには、Dominoディレクトリの検索を実行する2つのエージェントが含まれています。一方のエージェント(Find users by first name)は、ユーザーの名(ファーストネーム)が、入力ボックスに入力した名前と一致するすべてのDominoディレクトリ文書を検索します。もう一方のエージェント(Find group members)は、指定されたグループに属するすべてのユーザー文書を検索します。サンプル・エージェントを実行するには、図3に示す3つのデータベースが必要です。
図3.サンプル・エージェント用のデータベース ![]() これらの3つのデータベースは、「ダウンロード」セクションにあるZIPファイルに含まれています。 図2と図4に示すように、[Digest Search2]データベースで、[Demo NAB]データベースと[Demo Index]データベースの場所を設定する必要があります。データベースのパスを設定した後は、[Demo NAB]データベースに含まれる情報を使用して、索引データベースを生成しなければなりません。これを行うには、[Configuration]ビューで[Synchronize Index]をクリックします(図4参照)。 図4.[Configuration]ビューのアクション・ボタン![]() 索引の作成が完了したら、検索を実行できます。まず、[Find persons by first name]または[Find all users in a group]をクリックします。次に、ユーザーのファーストネームまたはグループ名を入力し、[OK]をクリックします。この例では、ユーザーのファーストネームは「John」です。この名前は、ご使用になるディレクトリーに存在する適当な名前に変更できます(図5参照)。 図5.ファーストネームによる検索![]() すべてが適切に設定されている場合は、図6のようなウィンドウが表示されます。 図6.ファーストネームによる検索の結果![]() [Find all users in a group]をクリックすると、次のバックグラウンド・イベントが発生します。
DigestSearchの使用が適するケースと適さないケースDigestSearchは、単一のキーワードを使用して1つ以上の文書を素早く検索するときに使用します。プロフィール文書やデータの一時保存用の文書は、DigestSearchが最も適している領域です。同様に、何らかの理由で従来の検索方法を使用できないにもかかわらず、高いパフォーマンスの検索ソリューションが必要な場合にもDigestSearchを使用します(Dominoディレクトリのような静的なデータが適しています)。 DigestSearchを使用することを検討した方がよい実例を示します。
DigestSearchを使用しない方がよい実例は、次のとおりです。
もともと、DigestSearchメソッドは、大量のSQLレコードをLotus Dominoデータベースと同期するときの速度を改善するために作成されました。各SQLレコードには固有のUnique Sequence Numberがあり、レコード内のすべての結合済みフィールドのカスタム固有番号を計算することができます。各レコードは1回だけ存在します。これは、DigestSearchメソッドを適用するために最も適した状況です。既存の文書(私たちのケースでは、1,000,000を超える文書)を配列またはリストにキャッシュすることを避けられるため、同期の時間を25分から10分に削減できます。
DigestSearchの次のバージョンに向けて必要なこと前述のように、DigestSearchには改良の余地があります。解決が簡単なものも、新しいアプローチが必要なものもあります。DigestSearchメソッドの次のバージョンで、私たちが計画している変更点は次のとおりです。
速度が重要標準的な状況では、DigestSearchは通常の検索方法よりも素早く結果を得られます。FTSearchやDBSearchによる高度な検索ほどの機能は必要としないが、プロフィール文書、GetDocumentByKeyメソッド、@DBLookupの代わりとなる方法を探している場合は、サンプル・データベースをダウンロードし、DigestSearchが役に立つかどうかを確認してください。この記事に掲載されている例とサンプル・データベースを用いることにより、DigestSearchの機能を簡単にテストできます。また、設定文書を変更するだけで、DigestSearchをご自分のアプリケーションに実装できます。
ダウンロード
リソース学ぶ
筆者について(原文のまま)Andrei Kouvchinnikov is a certified Principal Domino Developer and Administrator. His experience includes full life cycle development of Lotus Domino applications running on multiple platforms and development of applications for QuickPlace and Sametime. He has been working with the Lotus Domino platform since R4.5 for OS2. You can reach Andrei at andrei@botstation.com.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||