プログラムによるテキスト・データのロード
iKnow でテキスト・データを分析するには、まず、データ・ソースをドメインにロードする必要があります。これは、以下の 3 通りの方法で実行できます。
-
iKnow アーキテクトを使用して、ドメインのソース・テキストのデータ位置を指定します。[ビルド] ボタンで、指定したソースをドメインにロードします。
-
%iKnow.DomainDefinitionOpens in a new tab サブクラスを作成すると、ドメイン用のソース・テキストのデータ位置を指定できます。このサブクラスは、このデータをロードするロジックを含んでいる依存クラス内に、%Build() メソッドを生成します。
-
ローダとリスタをプログラムで指定して、この章で説明するように、指定したソースをドメインにロードします。
iKnow 分析に向けてテキスト・データを準備するために、ドメインではローダとリスタのインスタンスを呼び出す必要があります。ローダはリスタとプロセッサを使用して、テキスト・ソースに対する iKnow の処理を監督します。リスタは、ローダが使用するテキスト・ソースを識別します。iKnow は各種のソース・テキスト・データ用にさまざまなリスタを提供しています。各リスタは既定により、対応するプロセッサを既定のパラメータで自動的に呼び出します。ローダについては、あらゆるタイプのデータ・ソースに対して使用されるものが 1 つ用意されています。
ローダおよびリスタ・オブジェクトは任意の順序で作成できますが、これらは両方ともリスタの AddListToBatch() インスタンス・メソッドとローダの ProcessBatch() インスタンス・メソッド (または他の同等のリスタおよびローダ・メソッド) を呼び出す前に作成しておくことが必要です。
ローダ
ローダ (%iKnow.Source.LoaderOpens in a new tab) は、ロード・プロセスを調整するメイン・クラスです。ドメイン用に新しいローダ・オブジェクトを作成する必要があります。ローダ・オブジェクトを作成する手順は以下のとおりです。
SET domId=##class(%iKnow.Domain).GetOrCreateId("mydomain")
SET myloader=##class(%iKnow.Source.Loader).%New(domId)
ローダとリスタを作成したら、ソースをリストして処理するためのインスタンス・メソッドを発行します。例えば、バッチ・ロードを実行する場合は、リスタ AddListToBatch() インスタンス・メソッドを発行して、テキスト・ソースをリストします。次に、ローダ ProcessBatch()Opens in a new tab インスタンス・メソッドを発行して、リストされたソースを処理します。このローダ・メソッドは、AddListToBatch() でマークされた場所をスキャンするリスタを呼び出してから、これらのドキュメントを読んで iKnow エンジンにプッシュするプロセッサを呼び出し、最後に iKnow エンジンがロードしたステージング・グローバルを処理する ^%iKnow.BuildGlobals ルーチンを呼び出します。
ローダ・エラーのログ
ロード処理が完了したものの、1 つまたは複数のソースのロードにエラーが発生した場合は、そのエラーはエラー・ログに記録されます。さまざまな深刻度のエラーを取得するには、GetErrors()Opens in a new tab メソッド、GetWarnings()Opens in a new tab メソッドおよび GetFailed()Opens in a new tab メソッドを使用できます。例えば、コンテンツのないソース・ファイルのロードを試みると、ロードの失敗というエラー (GetFailed()) が発生します。ソース・メタデータ内にエラーがある場合は、ロード・エラーの警告 (GetWarnings()) が発生します。
このあらゆる深刻度レベルでのエラー・メッセージのエラー・ログを消去するには、ClearLogs()Opens in a new tab メソッドを使用できます。
ローダの Reset()
ロード処理が予定した方法で完了せず、最初から始める必要がある場合は、以下のように、ローダ・インスタンスの Reset()Opens in a new tab メソッドを起動します。
DO myloader.Reset()
リスタ
リスタは、テキスト・ファイル、レコード、または iKnow によってインデックスを作成したい他の構造化されていないデータのソースを識別します。つまり、最終的にドメインのソースとなるすべてのテキストを識別します。iKnow におけるコンテンツのユニット (単位) はソースで、これは、テキスト・ファイル、SQL テーブルのレコード、RSS ポスト、または他のテキスト・ソースといった分析対象の任意のテキスト・ユニットを表します。
ソースは通常、複数の文を含むテキストです。ただし、ソースは、あらゆるタイプのコンテンツを含むことができます。例えば、123 という数字を含むファイルは、1 つの文を含むソースとして扱われます。コンテンツのないファイルは、ソースとしてリストされません。
すべてのリスタはクラス %iKnow.Source.ListerOpens in a new tab にあり、スキャン可能な独自のタイプのソースを持ちます。例えば、サブクラス %iKnow.Source.File.ListerOpens in a new tab はファイル・システムをスキャンし、サブクラス %iKnow.Source.RSS.ListerOpens in a new tab は、ブログ投稿など、XML ファイル形式の RSS Web フィードをスキャンします。各種のソースに対して、iKnow は 7 つのリスタを提供します。また、独自のカスタム・リスタも作成できます。
ほとんどのテキスト・ソースでは、リスタが必要とされます。ただし、文字列として直接指定されるテキストでは、リスタは必要とされません。
AddListToBatch()Opens in a new tab メソッドを使用して、特定のディレクトリ、SQL テーブル、または RSS フィードでソースをチェックするようにリスタに指示することができます。リスタ・パラメータは、実際のリスタ・クラスによって異なります。
リスタの初期化
該当するタイプのリスタの %New()Opens in a new tab メソッドを使用してドメイン ID を指定し、ドメインのリスタ・インスタンスを作成できます。以下の例では、指定のドメイン内に 2 つのリスタを作成しています。
SET domId=##class(%iKnow.Domain).GetOrCreateId("mydomain")
SET flister=##class(%iKnow.Source.File.Lister).%New(domId)
WRITE flister,!
SET rlister=##class(%iKnow.Source.RSS.Lister).%New(domId)
WRITE rlister
各リスタは、以下のように対応するプロセッサを自動的に呼び出します。
-
File.Lister が File.Processor を呼び出します。
-
Global.Lister が Global.Processor を呼び出します。
-
Domain.Lister が Domain.Processor を呼び出します。
-
他のすべてのリスタが Temp.Processor を呼び出します。%iKnow.Source.Temp.Processor は、ロード・プロセス時に iKnow によって自動的に作成されて削除される一時グローバルを処理するため、このような名前を持っています。
各プロセッサは既定のプロセッサ・パラメータを有しており、それらはほとんどの iKnow ソースに適合します。したがって、ほとんどの場合、プロセッサまたはプロセッサ・パラメータを指定する必要がありません。プロセッサを指定しない場合、DefaultProcessor() メソッドで示されるように、iKnow は既定のプロセッサを使用します。
リスタ・インスタンス既定のオーバーライド
ほとんどの場合、リスタ・インスタンス既定は iKnow ソースの処理に適合しています。
構成、プロセッサ、またはコンバータ・オブジェクトのリスタ・インスタンス既定をオーバーライドする場合は、任意でInit()Opens in a new tab インスタンス・メソッドを使用して、リスタ・インスタンスを初期化できます。Init() を省略すると、既定値が使用されます。
以下にリスタの完全な初期化を示します。
Init(config,processor,processorparams,converter,converterparams)
これらのどの項目に対しても既定を指定する場合、空の文字列 ("") を Init() パラメータ値として指定します。
これらのオブジェクトは、SetConfig()Opens in a new tab、SetProcessor()Opens in a new tab、および SetConverter()Opens in a new tab メソッドを使用して別個に初期化することもできます。
-
構成 (Config) : 構成を指定しない場合、iKnow は既定の構成を使用します。構成では、テキスト・ドキュメントに含まれる言語のほか、自動言語識別を使用するかどうかを指定します。構成オブジェクトはドメイン固有ではなく、複数のドメインに同じ構成を使用できます。必須ではありませんが、構成は明示的に指定することが推奨されます。
-
プロセッサ : lister.Init() を使用して、プロセッサとプロセッサ・パラメータを指定できます。プロセッサは iKnow にテキストを読み込みます。プロセッサの指定はオプションです。プロセッサを指定しない場合、iKnow は既定のプロセッサとその既定のパラメータを使用します。プロセッサを指定する場合は、以下の例に示すように、プロセッサのパラメータ値を指定できます。
SET flister=##class(%iKnow.Source.File.Lister).%New(domId) SET processor="%iKnow.Source.File.Processor" SET pparams=$LB("Latin1") DO flister.Init("",processor,pparams,"","")
明示的に指定すると、プロセッサ・サブクラスはリスタ・サブクラスと同じタイプか (例えば、%iKnow.Source.File.ListerOpens in a new tab は %iKnow.Source.File.ProcessorOpens in a new tab を使用します)、またはリスタ・サブクラスに対応するプロセッサ・サブクラスがない場合には、%iKnow.Source.Temp.ProcessorOpens in a new tab となるかのいずれかである必要があります。また、独自のカスタム・プロセッサも作成できます。
プロセッサ・パラメータは Caché リストとして指定します。%iKnow.Source.File.ProcessorOpens in a new tab では、最初のリスト要素は、使用される文字セットの名前になります (例 : "Latin1")%iKnow.Source.Temp.ProcessorOpens in a new tab はプロセッサ・パラメータを取りません。
-
コンバータ : lister.Init() を使用して、ユーザ定義のコンバータとコンバータ・パラメータを指定できます。コンバータはフォーマットされたソース・ドキュメントを平文に変換して、HTMLやXML タグ、PDF フォーマット、または他のテキスト以外のコンテンツを除去します。通常は、それぞれのソース・ドキュメントの形式ごとに別個のコンバータを使用します。コンバータの指定はオプションです。既定では、コンバータは使用しません。コンバータを使用しない場合は、iKnow はフォーマット・コンテンツとテキスト・コンテンツの両方にインデックスを作成します。
リスタによるソースへの ID の割り当て
リスタは次の 2 つの一意の ID をそれぞれのソースに割り当てます。
-
ソース ID (内部 ID) : iKnow が割り当てる一意の整数値で、iKnow の内部処理に使用されます。
-
外部 ID : 一意の識別文字列または数字。外部 ID は、iKnow の使用を希望する任意のユーザ指定アプリケーションのためのリンクとして使用されます。外部 ID は以下の構造を持っています。
FeedbackOpens in a new tabListerReference:FullReference
Lister Reference (リスタ参照) は、このソースのロードに使用されるリスタ・クラスの完全なクラス名、またはリスタ・クラス自身が定義する短いエイリアスになり、接頭語としてコロンが付きます。Full Reference (完全参照) は、リスタ・クラスによって形式が定義される文字列です。これには、グループ名とローカル参照が含まれます。この完全参照からグループ名とローカル参照を派生させ、グループ名とローカル参照から完全参照を再構築するための実装の提供は、リスタ次第です。
例えば、テキスト・ファイルの外部 ID :FILE:c:\mytextfiles\mydoc.txt は、以下から構成されます。
-
ListerReference : リスタ・クラス・エイリアス :FILE
-
FullReference : c:\mytextfiles\mydoc.txt、これはグループ名 c:\mytextfiles\ とローカル参照 mydoc.txt から構成されます。
SQL テーブルのデータの場合、ListerReference は :SQL になります。グループ名は一意の値を含むレコード内のフィールドである groupfield で、ローカル参照は行 ID です。
文字列やグローバル変数のデータの場合、ListerReference は :TEMP になります。
ここで説明する外部 ID 形式は既定であり、外部 ID 形式は、SimpleExtIds ドメイン・パラメータを使用して構成できます。
いずれかの ID を使用して、ソースにアクセスできます。%iKnow.Queries.SourceAPIOpens in a new tab クラスには、これらの ID にアクセスするためのメソッドが含まれます。GetByDomain()Opens in a new tab メソッドは、それぞれのソースについて両方の ID を返します。ソース ID を指定すると、GetExternalId()Opens in a new tab メソッドは、外部 ID を返します。外部 ID を指定すると、GetSourceId()Opens in a new tab メソッドは、ソース ID を返します。
リスタ・クラス・エイリアスは、%iKnow.Source.File.ListerOpens in a new tab クラスの GetAlias()Opens in a new tab メソッドを使用して判断できます。エイリアスが存在しない場合は、外部 ID には完全なリスタ・クラス名が含まれます。
リスタの既定値の例
以下に、すべての既定値を使用する、最小限のリスタとローダの例を示します。この例では、ドメインを確立してから、そのドメインのリスタおよびローダ・インスタンス・オブジェクトを作成します。lister.Init() は呼び出さずに、構成、プロセッサ、およびコンバータの既定値を使用します。その後、ユーザが定義した .txt ファイルと .log ファイルのディレクトリをリストして、ロードします。
SET domId=##class(%iKnow.Domain).GetOrCreateId("mydomain") SetListerAndLoader SET mylister=##class(%iKnow.Source.File.Lister).%New(domId) SET myloader=##class(%iKnow.Source.Loader).%New(domId) UseListerAndLoader SET install=$SYSTEM.Util.InstallDirectory() SET dirpath=install_"mgr\Temp\iknow\mytextfiles" SET stat=mylister.AddListToBatch(dirpath,$LB("txt","log"),0,"") WRITE "The lister status is ",$System.Status.DisplayError(stat),! SET stat=myloader.ProcessBatch() WRITE "The loader status is ",$System.Status.DisplayError(stat),!
このドキュメントのほとんどの例では、リスタやローダを使用する前に古いデータを削除しています。古いデータの削除は、デモでこれらの例を繰り返し実行できるようにするために行われています。このドキュメントのほとんどの例では、プロセッサとプロセッサ・パラメータを指定せずに、既定を採用しています。このドキュメントの多くの例では、構成についてはその既定値を採用するのではなく、値を指定しています。
リスタ・パラメータ
ソースを指定するメソッドを呼び出す場合は、リスタ・パラメータを指定します。AddListToBatch()Opens in a new tab リスタ・インスタンス・メソッド (大量のバッチ・ソース・ロード向け) および ProcessList()Opens in a new tab ローダ・インスタンス・メソッド (既存のソース・バッチに少数のソースを追加する場合) には、同じリスタ・パラメータを指定します。
以下の 4 つのリスタ・パラメータの累積によって、iKnow インデックス作成用にリストするソースが定義されます。
-
Path : ソースが置かれる場所で、文字列で指定します。このパラメータは必須です。
-
Extensions : リストするソースを識別する 1 つまたは複数のファイル拡張子接尾語。Caché リスト・データ構造として指定し、それぞれの要素は文字列になります (Caché リスト・データ構造の詳細は "$LISTBUILD" を参照してください)。既定では、リスタは、パス・ディレクトリにあるファイルの中でデータを含むすべてのファイルを、そのファイル拡張子接尾語に関係なく選択します。これには、ファイル拡張子接尾語を持たないファイルや、テキスト以外のファイル拡張子接尾語 (.jpg など) を持つファイルも含まれます。空のファイルは選択されません。ディレクトリは選択されません。拡張子接尾語パラメータを指定すると、リスタはパス・ディレクトリ内でデータを含むファイルのうち、そのファイル拡張子接尾語を持つ (またはファイル拡張子接尾語のない) ファイルのみを選択します。
-
Recursive : パスのサブディレクトリでソースを検索するかどうかを指定するブーリアン値。選択すると、複数レベルのサブディレクトリについてソースを検索します。1 = サブディレクトリを含めます。0 = サブディレクトリを含めません。既定値は 0 です。
-
Filter : iKnow インデックス作成用にリストするソースを制限するために使用するフィルタを指定する文字列。例えば、ユーザが設計したフィルタによって、ファイル名に指定の部分文字列を持つファイルのみにリスタを制限できます。既定では、フィルタは使用しません(ここで言及されている “フィルタ“ は、%iKnow.Filters クラスのフィルタとはまったく異なります。後者のフィルタは、iKnow クエリに供給されたインデックス作成済みのソースを含めたり除外したりするために使用されます)。
バッチとリスト
iKnow は、あらゆるタイプのソースをロードするために、バッチ・ロード (ProcessBatch()) とリスト・ロード (ProcessList()) という 2 つの方法を提供しています。どちらの方法も同じ処理を実行しますが、実行速度が異なります。どちらを使用するかは、主として、ロードするソースの数によって決まります。原則としては、ロードするソースが 10 個以下の場合は ProcessList() を使用し、100 個以上のソースをロードする場合は ProcessBatch() を使用します。11 ~ 99 個のソースをロードする際にどちらを使用するかは、特定のソースの性質によって決まります。
リストとロードの例
このセクションの例では、ソースをロードするためのさまざまな方法を示します。
-
lister.AddListToBatch()Opens in a new tab と loader.ProcessBatch()Opens in a new tab を使用して、多数のソースをバッチ・ロードします。
-
loader.SetLister()Opens in a new tab と loader.ProcessList()Opens in a new tab を使用して、少数のソースをロードしたり、既存のバッチ・ロードにソースを追加します。
-
loader.BufferSource()Opens in a new tab とloader.ProcessBuffer()Opens in a new tab を使用して、ソースとして文字列をロードします。もちろん、文字列を含むローカルまたはグローバル変数を指定できます。
また、loader.ProcessVirtualList() または loader.ProcessVirtualBuffer() を使用して、仮想ソースとしてソースをロードすることもできます。詳細は "仮想ソースのロード" を参照してください。
ファイルのロード
以下の実行可能サンプル・プログラムは、Windows ディレクトリ dirpath 内にある拡張子 .txt または .log を持つソース・ファイルのバッチ・ロードを実行します。
DomainCreateOrOpen SET dname="mydomain" IF (##class(%iKnow.Domain).Exists(dname)) { SET domoref=##class(%iKnow.Domain).Open(dname) GOTO DeleteOldData } ELSE { SET domoref=##class(%iKnow.Domain).%New(dname) DO domoref.%Save() GOTO SetEnvironment } DeleteOldData SET stat=domoref.DropData() IF stat { GOTO SetEnvironment } ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat) QUIT} SetEnvironment SET domId=domoref.Id IF ##class(%iKnow.Configuration).Exists("myconfig") { SET cfg=##class(%iKnow.Configuration).Open("myconfig") } ELSE { SET cfg=##class(%iKnow.Configuration).%New("myconfig",0,$LISTBUILD("en"),"",1) DO cfg.%Save() } CreateListerAndLoader SET flister=##class(%iKnow.Source.File.Lister).%New(domId) DO flister.Init("myconfig","","","","") SET myloader=##class(%iKnow.Source.Loader).%New(domId) UseListerAndLoader SET install=$SYSTEM.Util.InstallDirectory() SET dirpath=install_"mgr\Temp\iknow\mytextfiles" SET stat=flister.AddListToBatch(dirpath,$LB("txt","log"),0,"") WRITE "The lister status is ",$System.Status.DisplayError(stat),! SET stat=myloader.ProcessBatch() WRITE "The loader status is ",$System.Status.DisplayError(stat),! QueryLoadedSources WRITE ##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId)," sources"
この例は、多数のファイルのロードに適したバッチ・ロードを実行します。少数のファイルをロードするには、SetLister()Opens in a new tab および ProcessList()Opens in a new tab メソッドを使用します。
SQL レコードのロード
以下の実行可能サンプル・プログラムは、Cinema.Review テーブルのレコードのバッチ・ロードを実行します。これは、各レコードの ReviewText フィールド値をソース・テキストとしてロードします。SQL クエリにエラーがある場合、ローダはエラー・ステータスを返します。
SQL データをロードする iKnow プログラムは、%iKnow.Source.SQL.Lister を使用する必要があります。このリスタでは、常に %iKnow.Source.Temp.Processor を呼び出していますが、パラメータは使用していません。したがって、ユーザ専用のカスタム・プロセッサを作成していない限り、プロセッサを指定する理由はありません。
ZNSPACE "Samples" DomainCreateOrOpen SET dname="mydomain" IF (##class(%iKnow.Domain).Exists(dname)) { WRITE "The ",dname," domain already exists",! SET domoref=##class(%iKnow.Domain).Open(dname) GOTO DeleteOldData } ELSE { WRITE "The ",dname," domain does not exist",! SET domoref=##class(%iKnow.Domain).%New(dname) DO domoref.%Save() WRITE "Created the ",dname," domain with domain ID ",domoref.Id,! GOTO SetEnvironment } DeleteOldData SET stat=domoref.DropData() IF stat { WRITE "Deleted the data from the ",dname," domain",!! GOTO SetEnvironment } ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat) QUIT} SetEnvironment SET domId=domoref.Id IF ##class(%iKnow.Configuration).Exists("myconfig") { SET cfg=##class(%iKnow.Configuration).Open("myconfig") } ELSE { SET cfg=##class(%iKnow.Configuration).%New("myconfig",0,$LISTBUILD("en"),"",1) DO cfg.%Save() } CreateListerAndLoader SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId) DO flister.Init("myconfig") SET myloader=##class(%iKnow.Source.Loader).%New(domId) QueryBuild SET myquery="SELECT Top 25 ID AS UniqueVal,Type,NarrativeFull,EventDate FROM Aviation.Event" SET idfld="UniqueVal" SET grpfld="Type" SET dataflds=$LB("NarrativeFull") UseLister SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds) IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT } UseLoader SET stat=myloader.ProcessBatch() IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT } QueryLoadedSources WRITE ##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId)," sources loaded"
この例は、多数の SQL レコードのロードに適したバッチ・ロードを実行します。少数の SQL レコードをロードするには、SetLister()Opens in a new tab および ProcessList()Opens in a new tab メソッドを使用します。
また、%SYSTEM.iKnowOpens in a new tab ユーティリティ・メソッド IndexTable()Opens in a new tab も使用できます。
添え字付きグローバルの要素のロード
以下の実行可能サンプル・プログラムは、添え字付きグローバルの要素をロードします。ここでは %iKnow.Source.Global.Lister を使用して、ProcessList()Opens in a new tab メソッドに対するリスタ・パラメータとしてグローバル名、最初の添え字 (これを含む)、および最後の添え字 (これを含む) を指定します。この例では、Samples ネームスペース内にある ^Aviation.AircraftD グローバルを使用しています。これはスパース配列であるため、1 ~ 50,000 の添え字のごく一部しかデータを含んでいません。
DomainCreateOrOpen ZNSPACE "Samples" SET dname="mydomain" IF (##class(%iKnow.Domain).Exists(dname)) { SET domoref=##class(%iKnow.Domain).Open(dname) GOTO DeleteOldData } ELSE { SET domoref=##class(%iKnow.Domain).%New(dname) DO domoref.%Save() GOTO SetEnvironment } DeleteOldData SET stat=domoref.DropData() IF stat { GOTO SetEnvironment } ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat) QUIT} SetEnvironment SET domId=domoref.Id IF ##class(%iKnow.Configuration).Exists("myconfig") { SET cfg=##class(%iKnow.Configuration).Open("myconfig") } ELSE { SET cfg=##class(%iKnow.Configuration).%New("myconfig",0,$LISTBUILD("en"),"",1) DO cfg.%Save() } ListerAndLoader SET mylister=##class(%iKnow.Source.Global.Lister).%New(domId) DO mylister.Init("myconfig","","","","") SET myloader=##class(%iKnow.Source.Loader).%New(domId) SET stat=myloader.SetLister(mylister) IF stat '= 1 { WRITE "SetLister error ",$System.Status.DisplayError(stat) QUIT} SET gbl="^Aviation.AircraftD" SET stat=myloader.ProcessList(gbl,1,50000) IF stat '= 1 { WRITE "ProcessList error ",$System.Status.DisplayError(stat) QUIT } SourceSentenceQueries SET numSrcD=##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId) WRITE "The domain contains ",numSrcD," sources",! SET numSentD=##class(%iKnow.Queries.SentenceAPI).GetCountByDomain(domId) WRITE "These sources contain ",numSentD," sentences"
ProcessList() メソッドは、一度に 1 つの添え字レベルしか指定できません。複数の添え字レベルを繰り返すためには、コードを記述して、目的の添え字レベルでこのメソッドを呼び出す必要があります。例えば、セカンド・レベル添え字の 1 および 2 をロードするには、以下のようなコードを記述します。
FOR i=1:1:90000 { SET gbl="^Aviation.NarrativeS("_i_")" SET stat=myloader.ProcessList(gbl,1,2) }
これにより、^Aviation.NarrativeS(85879,1) および ^Aviation.NarrativeS(85879,2) などのグローバルがロードされます。
文字列のロード
以下の実行可能サンプル・プログラムは、1 つのグローバル (または文字列リテラル) をソース・ファイルとしてロードします。文字列をロードする際はリスタは不要であることに注意してください。構成を指定して、ProcessBuffer() メソッドにて適用することができます。
ConfigurationCreateOrOpen IF ##class(%iKnow.Configuration).Exists("EnFr") { SET cfg=##class(%iKnow.Configuration).Open("EnFr") } ELSE { SET cfg=##class(%iKnow.Configuration).%New("EnFr",1,$LB("en","fr")) DO cfg.%Save() } DomainCreateOrOpen SET dname="mydomain" IF (##class(%iKnow.Domain).Exists(dname)) { WRITE "The ",dname," domain already exists",! SET domoref=##class(%iKnow.Domain).Open(dname) GOTO DeleteOldData } ELSE { WRITE "The ",dname," domain does not exist",! SET domoref=##class(%iKnow.Domain).%New(dname) DO domoref.%Save() SET domId=domoref.Id WRITE "Created the ",dname," domain with domain ID ",domId,! GOTO CreateLoader } DeleteOldData SET stat=domoref.DropData() IF stat { WRITE "Deleted the data from the ",dname," domain",!! SET domId=domoref.Id GOTO CreateLoader } ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat) QUIT} CreateLoader SET myloader=##class(%iKnow.Source.Loader).%New(domId) UseLoader SET ^a="I drove at 70mph then sped up to 100mph when the light changed." DO myloader.BufferSource("ref",^a) DO myloader.ProcessBuffer("EnFr") QuerySources WRITE "number of sources:",##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId)
BufferSource() メソッドの最初の引数には、一意の外部ソース ID を指定します。以下の例では、それぞれのグローバル添え字について別個のソースを作成します。
SET i=1 WHILE $DATA(^a(i)) { DO myloader.BufferSource("ref"_i,^a(i)) DO myloader.ProcessBuffer() SET i=i+1 } WRITE "end of data"
また、%SYSTEM.iKnowOpens in a new tab ユーティリティ・メソッド IndexString()Opens in a new tab も使用できます。
ドメイン・コンテンツの更新
ドメインへのソースの初期ロードを実行した後で、ソースを追加または削除することで、このソース・リストを変更できます。ドメインを更新するには、ソース・テキストのセットでの変更への応答を参照します。これをドメインのアップグレードと混同しないようにします。ドメインのアップグレードでは、Caché の重要な新規バージョンをインストールした場合に、iKnow ソフトウェア内での変更への応答を参照します。
ソースの追加
(AddListToBatch() および ProcessBatch() メソッドを使用して) ドメインへのソースの初期ロードを実行した後で、ソース・リストにファイルを追加したい場合があります。これは SetLister()Opens in a new tab および ProcessList()Opens in a new tab メソッドを使用して行います。ProcessList() メソッドは、AddListToBatch() メソッドと同じパラメータを使用します。
-
一度に 1 つのソースを追加するには、以下のように指定します。SET stat=myloader.ProcessList("C:\mytextfiles\newfile.txt")
-
ソースのディレクトリを追加するには、以下のように指定します。SET stat=myloader.ProcessList("C:\mytextfiles\logfiles",$LB("log"),0,"")
バッチ・ロードにソースを追加する例を以下に示します。
DomainCreateOrOpen SET dname="mydomain" IF (##class(%iKnow.Domain).Exists(dname)) { SET domoref=##class(%iKnow.Domain).Open(dname) GOTO DeleteOldData } ELSE { SET domoref=##class(%iKnow.Domain).%New(dname) DO domoref.%Save() GOTO SetEnvironment } DeleteOldData SET stat=domoref.DropData() IF stat { GOTO SetEnvironment } ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat) QUIT} SetEnvironment SET domId=domoref.Id IF ##class(%iKnow.Configuration).Exists("myconfig") { SET cfg=##class(%iKnow.Configuration).Open("myconfig") } ELSE { SET cfg=##class(%iKnow.Configuration).%New("myconfig",0,$LISTBUILD("en"),"",1) DO cfg.%Save() } ListerAndLoader SET flister=##class(%iKnow.Source.File.Lister).%New(domId) DO flister.Init("myconfig","","","","") SET myloader=##class(%iKnow.Source.Loader).%New(domId) SET stat=myloader.SetLister(flister) SourceBatchLoad SET install=$SYSTEM.Util.InstallDirectory() SET dirpath=install_"mgr\Temp\iknow\mytextfiles" SET stat=flister.AddListToBatch(dirpath,$LB("txt"),0,"") SET stat=myloader.ProcessBatch() IF stat '= 1 { WRITE "Loader error ",$System.Status.DisplayError(stat) QUIT } QueryLoadedSources WRITE "Source count is ",##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId),! ExpandListofSources SET elister=##class(%iKnow.Source.File.Lister).%New(domId) DO elister.Init("myconfig") SET stat=myloader.SetLister(elister) SET addpath=install_"dev\Cache" SET stat=myloader.ProcessList(addpath,$LB("txt"),1,"") IF stat '= 1 { WRITE "The ProcessList loader status is ",$System.Status.DisplayError(stat) QUIT } QueryTotalSources WRITE "Expanded source count is ",##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId)
また、%SYSTEM.iKnowOpens in a new tab ユーティリティ・メソッド IndexFile()Opens in a new tab および IndexDirectory()Opens in a new tab も使用できます。
ソースの削除
DeleteSource()Opens in a new tab メソッドを使用すると、ドメインにロードされたソースを削除できます。このメソッドは、仮想ソースの削除には使用できません。仮想ソースの削除には、別に DeleteVirtualSource()Opens in a new tab メソッドが用意されています。いずれのメソッドも %SYSTEM.iKnowOpens in a new tab クラスにあります。
仮想ソースのロード
仮想ソースとは、静的ではないソースです。例えば、頻繁に変更されるファイルのために仮想ソースを使用する場合があります。仮想ソースの srcId は負の整数になります。仮想ソースの外部 ID は、ListerReference (リスタ・クラスのエイリアス、通常は :TEMP) から開始します。
仮想ソースを追加しても、iKnow の統計は更新されません。この理由から、ドメインの統計を改訂する手間を招かずに特定目的のためにソースを一時的に追加したい場合は、仮想ソースの使用が適していることがあります。書き込み中のソースなど、継続的に変更されるソースを追加する場合は、仮想ソースを使用するべきです。仮想ソース ID は負の数であるため、仮想ソースは通常のソースと簡単に区別できます。仮想ソースの削除と通常ソースの削除には、異なるメソッドが使用されます。
仮想ソースをロードするには、loader.SetLister()Opens in a new tab と loader.ProcessVirtualList()Opens in a new tab または loader.BufferSource()Opens in a new tab とloader.ProcessVirtualBuffer()Opens in a new tab を使用します。以下のプログラムは、ProcessVirtualBuffer() を使用して仮想ソースをロードしています。
DomainCreateOrOpen SET dname="mydomain" IF (##class(%iKnow.Domain).Exists(dname)) { WRITE "The ",dname," domain already exists",! SET domoref=##class(%iKnow.Domain).Open(dname) GOTO DeleteOldData } ELSE { WRITE "The ",dname," domain does not exist",! SET domoref=##class(%iKnow.Domain).%New(dname) DO domoref.%Save() SET domId=domoref.Id WRITE "Created the ",dname," domain with domain ID ",domId,! GOTO SetEnvironment } DeleteOldData /* This DOES NOT delete virtual sources */ SET stat=domoref.DropData() IF stat { WRITE "Deleted the data from the ",dname," domain",!! SET domId=domoref.Id GOTO SetEnvironment } ELSE { WRITE "DropData error ",$System.Status.DisplayError(stat) QUIT} SetEnvironment SET config="VSConfig" IF ##class(%iKnow.Configuration).Exists(config) { SET cfg=##class(%iKnow.Configuration).Open(config) } ELSE { SET cfg=##class(%iKnow.Configuration).%New(config,1) DO cfg.%Save() } CreateLoader SET myloader=##class(%iKnow.Source.Loader).%New(domId) VirtualSource SET node="",(total,status)=0 FOR { SET node=$ORDER(^VendorData(node),1,data) QUIT:node="" SET company=$LIST(data,1) QUIT:company="" SET address=$LTS($LIST(data,2)) SET total=total+1 SET status=myloader.BufferSource("SourceTest"_total,company) SET status=myloader.BufferSource("SourceTest"_total,address) } SET status=myloader.ProcessVirtualBuffer(config) SET vsrclist=myloader.GetSourceIds() FOR i=1:1:$LL(vsrclist) { SET srcid=-$LIST(vsrclist,i) WRITE "External Id=",##class(%iKnow.Queries.SourceAPI).GetExternalId(domId,srcid) WRITE " Source Id=",srcid,! WRITE " Sentence Count=",##class(%iKnow.Queries.SentenceAPI).GetCountBySource(domId,$lb(srcid)),! }
%iKnow.Queries.SourceAPI.GetCountByDomain() メソッドは仮想ソースをカウントしないことに注意してください。仮想ソースがロードされたかどうかは、%iKnow.Queries.SourceAPI.GetExternalId(domId,-1) を呼び出すことで判別できます。ここでの -1 は、ロードされた最初の仮想ソースの srcId です。
既定では、多くの iKnow クエリは通常のソースのみを処理して、仮想ソースは無視します。これらのクエリを使用して仮想ソースを処理するには、クエリ・メソッドに vSrcId パラメータ値を指定する必要があります。
仮想ソースの削除
%iKnow.Source.LoaderOpens in a new tab クラスは、仮想ソースを削除するための 2 つのメソッドを提供します。
-
DeleteVirtualSource()Opens in a new tab は、ドメインのインデックスが作成された 1 つの仮想ソースを削除します。ドメイン ID (正の整数) と仮想ソース ID (負の整数) を指定します。これによって、このソース・テキストに生成されたすべての iKnow エンティティが削除されます。
-
DeleteAllVirtualSources()Opens in a new tab は、指定のドメインのインデックスが作成されたすべての仮想ソースを削除します。これによって、これらのソース・テキストに生成されたすべての iKnow エンティティが削除されます。
ロードされたソース・データのコピーとインデックス再作成
ソースをドメインに正常にロードした後は、そのソースの一部またはすべてを別のドメインにコピーすることが必要な場合もあります。iKnow によってそのロードしたソースがコピーされると、そのソースのインデックスも再作成されます。したがって、そのコピーされたソースには別のソース ID とエンティティ ID が付与され、外部 ID は変更されません。
1 つのドメインから別のドメインにコピーまたは再インデックス付けが必要になる理由としては以下が考えられます。
-
ドメインのコピーを作成するため。バックアップ・コピーの作成、またはコピーを作成して特定の日時にドメインのスナップショットとして機能させることが必要な場合があります。例えば、RSS フィードのインデックスを作成する場合は、このフィードは時間と共に変化し、後日には元のソース・データにアクセスできなくなる可能性があるので、スナップショットの作成が必要な場合があります。
-
元のソース・セットのサブセットを含むドメインを作成するため。この新しいドメインは、扱うのにより小型で、効率性が高く、より簡単になります。このコピーされたソースのサブセットは、コピーするソース ID のリストで指定するか、またはコピーするソースを制限するフィルタで指定できます。例えば、最新のソースのみで構成されるドメインを作成することで、クエリの際に、各クエリの日付でフィルタする必要がなくなる可能性があります。
-
2 つのドメインからマージしたソース・セットを含むドメインを作成するため、または、1 つのドメインからすでにソースを含むドメインにソースを追加するため。
-
ソース・セットを抜本的に変更した後にドメイン内のソースのインデックスを再作成するため。例えば、ドメイン内で複数のソースの追加または削除を頻繁に行う場合は、インデックスの作成がすでに最適化されていない可能性があります。(通常のソースの追加および削除では、インデックスのパフォーマンスは低下しません。)ドメインをコピーすることで、現在コピーしているソースのインデックスを再作成し、新しいドメインのインデックス作成を最適化します。
-
iKnow 言語モデルにリビジョンを適用するため。iKnow のリリース・バージョンには通常、その言語モデルの改善点が含まれています。これらには、新しい言語へのサポートの導入やすでにサポートされている言語への改善点が含まれている可能性があります。ドメイン内のソース・セットをコピーすることで、そのソースのインデックスが再作成され、その結果、コピーされたソースに iKnow の最新の言語モデルが適用されます。
1つのドメインから別のドメインにコピーまたは再インデックス付けをするには、%iKnow.Source.Domain.ListerOpens in a new tab クラスを使用します。%New()Opens in a new tab メソッドを使用してこのクラスのリスタ・インスタンスを作成可能にするには、新しいドメインを定義しておく必要があります。ドメインは両方とも同じネームスペースに置く必要があります。
以下の例では、firstdomain ドメインを生成し、firstdomain のコンテンツを newdomain という名前の空のドメインにコピーすると、newdomain のコンテンツが自動的に再インデックス付けされます。
EstablishAndPopulateFirstDomain SET domOref=##class(%iKnow.Domain).%New("firstdomain") DO domOref.%Save() SET domId=domOref.Id SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId) SET myloader=##class(%iKnow.Source.Loader).%New(domId) SET myquery="SELECT Top 25 ID AS UniqueVal,Type,NarrativeFull,EventDate FROM Aviation.Event" SET idfld="UniqueVal" SET grpfld="Type" SET dataflds=$LB("NarrativeFull") SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds) IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT } SET stat=myloader.ProcessBatch() IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT } TestQueryFirstDomain WRITE ##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId)," sources in the from domain",! CreateSecondDomain SET domOref=##class(%iKnow.Domain).%New("newdomain") DO domOref.%Save() SET domNewId=domOref.Id CopyAndReindexFromFirstDomainToSecondDomain SET newlister=##class(%iKnow.Source.Domain.Lister).%New(domNewId) SET newloader=##class(%iKnow.Source.Loader).%New(domNewId) SET stat=newlister.AddListToBatch(domId) SET stat=newloader.ProcessBatch() TestQuerySecondDomain WRITE ##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domNewId)," sources in the to domain" CleanUpForNextTime SET stat=##class(%iKnow.Domain).%DeleteId(domId) IF stat '= 1 {WRITE "Domain delete error:",stat } SET stat=##class(%iKnow.Domain).%DeleteId(domNewId) IF stat '= 1 {WRITE "Domain delete error:",stat }
AddListToBatch()Opens in a new tab メソッドによって 2 番目のリスタ・パラメータが取得され、コピーするソースを指定できます。また、ソースのリスト (コンマで区切られたソース ID の整数値のリスト) またはフィルタのいずれかを指定できます。以下の例は、コンマで区切られたソース ID のリストを指定することによってコピーするソースを制限する点を除いては、前述の例と同じです。
EstablishAndPopulateFirstDomain SET domOref=##class(%iKnow.Domain).%New("firstdomain") DO domOref.%Save() SET domId=domOref.Id SET flister=##class(%iKnow.Source.SQL.Lister).%New(domId) SET myloader=##class(%iKnow.Source.Loader).%New(domId) SET myquery="SELECT Top 25 ID AS UniqueVal,Type,NarrativeFull,EventDate FROM Aviation.Event" SET idfld="UniqueVal" SET grpfld="Type" SET dataflds=$LB("NarrativeFull") SET stat=flister.AddListToBatch(myquery,idfld,grpfld,dataflds) IF stat '= 1 {WRITE "The lister failed: ",$System.Status.DisplayError(stat) QUIT } SET stat=myloader.ProcessBatch() IF stat '= 1 {WRITE "The loader failed: ",$System.Status.DisplayError(stat) QUIT } TestQueryFirstDomain WRITE ##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domId)," sources in the from domain",! CreateSecondDomain SET domOref=##class(%iKnow.Domain).%New("newdomain") DO domOref.%Save() SET domNewId=domOref.Id SubsetOfSourcesToCopy SET subset="1,3,5,7,9,11,13,15,17,19" CopyAndReindexFromFirstDomainToSecondDomain SET newlister=##class(%iKnow.Source.Domain.Lister).%New(domNewId) SET newloader=##class(%iKnow.Source.Loader).%New(domNewId) SET stat=newlister.AddListToBatch(domId,subset) SET stat=newloader.ProcessBatch() TestQuerySecondDomain WRITE ##class(%iKnow.Queries.SourceAPI).GetCountByDomain(domNewId)," sources in the to domain" CleanUpForNextTime SET stat=##class(%iKnow.Domain).%DeleteId(domId) IF stat '= 1 {WRITE "Domain delete error:",stat } SET stat=##class(%iKnow.Domain).%DeleteId(domNewId) IF stat '= 1 {WRITE "Domain delete error:",stat }
UserDictionary とコピーされたソース
ソースがリストされると、UserDictionary が適用されます。したがって、初期ロード時のソースに行われた UserDictionary の変更はすべて、コピーされたソースに反映されています。ただし、コピー処理はリスト処理でもあるため、新しい UserDictionary を適用して、そのソースをコピーされたソースと同様に変更することもできます。
例えば、ソースの最初のリスト時に使用された UserDictionary で、“Doctor“ の省略形として “Dr.“ を代入した場合は、この代入がコピーされたソースに反映されます。その後、UserDictionary を変更して “doctor“ に “physician“ も代入するとします。UserDictionary へのこの変更は、すでにロードされたソースには何の影響も与えません。ソースをコピーすると、この UserDictionary への変更が適用されます。“Dr.“ を “doctor“ に代入した回数が 0 回になるのは、その代入が初期ロード時のソースにすでに存在するからであり、“physician“ の “doctor“ への代入はコピーされたソースで実行済みとなっています。
-