MarkLogic Data Hubのカスタマイズ – パート1 : トリプルを作成する

投稿者: 太田佳伸 投稿日: 2020年3月12

Data Hubでトリプルを作成し、Groveで表示する

これから数回にわたりData Hubのカスタマイズを紹介します。
今回と次回の記事で、これまでのData HubとGroveの紹介をベースに、以下のステップを解説します。

1. Data Hubのカスタムステップでドキュメントにトリプルを追加する

a. CSVファイルに一つ新しい項目を追加し、その追加による影響が非常に少ないことを示します。
b. 追加した項目に対するプロパティをエンティティに追加します。
c. トリプルをドキュメントに追加するカスタムステップを作成します。
d. トリプルに対するSPARQLクエリを実行し、検索可能であることを示します。

2. Groveの詳細ページにおいてドキュメントの内容とともに、作成したトリプルを表示するようなUIを作成する

a.  JSONTreeというReactコンポーネントを使用した詳細ページを作成します。
b.  visjs-graphをインストールします。
npm
mlpm
c. GraphContainerコンポーネントを詳細ページに組み込みます。
前回のGroveの説明では、MarkLogicサーバのバージョン10.0.0以降を使用している場合にはデプロイメントがうまくいかないことがありました。修正もここで説明しています。)

1. Data Hubのカスタムステップでドキュメントにトリプルを追加する

Data Hubの紹介としてこれまで2回掲載しました。
Data Hub QuickStart チュートリアル – ビジネス課題の解決から考えるデータ統合の進め方 <前編>
Data Hub QuickStart チュートリアル – ビジネス課題の解決から考えるデータ統合の進め方 <後編>

今回は、この2回で作成したデータハブを使用します。使用したデータは以下のようなものでした。

customer1.csv
id,Kanji_sei,Kana_sei,Kanji_mei,Kana_mei,Gender,Pref,Address,Tel,Date
0001,田中,たなか,一郎,いちろう,男,東京都,中野区中野1ー1−1,03-1274-7834,1990/3/31
0002,鈴木,すずき,大輝 ,だいき,男,千葉県,野田市清水33-1,03-2421-3416,1995/1/20
0003,佐藤,さとう,美咲,みさき,女,東京都,世田谷区北沢3-2-4,03-5621-3663,1997/6/5
0004,伊藤,いとう,健太,けんた,男,神奈川県,川崎市高津区5-3-2,07-3421-3456,1969/6/27
0005,吉田,よしだ,遥,はるか,女,東京都,渋谷区神宮前6-12-9,03-4563-2345,1964/4/14
0006,松本,まつもと,杏奈,あんな,女,東京都,千代田区丸の内3-2-1,03-5675-3466,1995/7/22
0007,清水,しみず,彩香,あやか,女,千葉県,柏市柏43-3-1,07-2324-5621,1974/7/2
0008,青木,あおき,諒,りょう,男,神奈川県,横浜市青葉区4-3-2,05-4233-4322,1981/5/2
0009,中野,なかの,達也,たつや,男,東京都,足立区千住12-4-3,03-5343-4356,1982/8/25
0010,坂本,さかもと,裕太,ゆうた,男,東京都,練馬区石神井町12-3-4,03-4452-3453,1983/9/11

この顧客情報に新しく紹介者の情報が増えたと想定し、その紹介者の関係をグラフで表示することでインフルエンサーを見つけてみたいと思います。
上記のCSVに新しい項目としてintroducedByという項目が追加され、そこでは顧客を紹介してくれた人のIDが入っているということで、具体的には以下のようになります。

customer1.csv
id,Kanji_sei,Kana_sei,Kanji_mei,Kana_mei,Gender,Pref,Address,Tel,Date,introducedBy
0001,田中,たなか,一郎,いちろう,男,東京都,中野区中野1ー1−1,03-1274-7834,1990/3/31,
0002,鈴木,すずき,大輝 ,だいき,男,千葉県,野田市清水33-1,03-2421-3416,1995/1/20,0001
0003,佐藤,さとう,美咲,みさき,女,東京都,世田谷区北沢3-2-4,03-5621-3663,1997/6/5,0001
0004,伊藤,いとう,健太,けんた,男,神奈川県,川崎市高津区5-3-2,07-3421-3456,1969/6/27,0002
0005,吉田,よしだ,遥,はるか,女,東京都,渋谷区神宮前6-12-9,03-4563-2345,1964/4/14,0002
0006,松本,まつもと,杏奈,あんな,女,東京都,千代田区丸の内3-2-1,03-5675-3466,1995/7/22,0003
0007,清水,しみず,彩香,あやか,女,千葉県,柏市柏43-3-1,07-2324-5621,1974/7/2,0002
0008,青木,あおき,諒,りょう,男,神奈川県,横浜市青葉区4-3-2,05-4233-4322,1981/5/2,0003
0009,中野,なかの,達也,たつや,男,東京都,足立区千住12-4-3,03-5343-4356,1982/8/25,0001
0010,坂本,さかもと,裕太,ゆうた,男,東京都,練馬区石神井町12-3-4,03-4452-3453,1983/9/11,0001

このようなデータ項目の追加変更はよくあることですが、MarkLogicでは、もしこれらの項目を使用する予定がないのであれば既存のアプリケーション等に特に変更は必要ありません。
実際に、このデータを以前に作成したデータハブのCustomer1というフローでロードすると、次のようにロードできることが分かります。

次に、新しく導入した紹介者(introducedBy)項目をトリプルの関係性で使用するため、エンティティを更新します。エンティティの変更はエンティティの編集ボタンをクリックして行います。
新規に作成した時と同様にintroducedByというプロパティ名とデータ型としてstringを選択してSaveボタンをクリックします。
Saved.Update indexes in MarkLogic?というプロンプトに対してはYesをクリックします。

次にマッピングを更新します。Customer1のフローに戻り、MappingCustomer1を修正します。
MappingCustomer1を開くと、EntityにintroducedByという項目が追加されています。Xpath Expressionには、ドロップダウンからintroducedByを選択します。

これで新しく導入されたデータをこれまでのデータと同様にハーモナイズされた形で使用することができるようになりました。次にこの新項目からトリプルを作成するカスタムステップを作っていきます。

カスタムステップの作成

カスタムステップの作成には2つの手順が必要です。フローにカスタムステップを追加することと、カスタムステップが呼び出すモジュールを作成することです。
まずはCustomer1フローにカスタムステップを追加します。これはData HubのQuickStartで実行できます。
NEW STEPボタンをクリックして、New Stepのポップアップウィンドウから
Step Type : Custom
Custom Step Type: Other
を選択し、以下の画面のような情報を入力します。

Name : AddTripleCustomer1
Source Type:Collection
Source Collection:MappingCustomer1
Target Entity:Customer
Advanced Setting
Source Database:data-hub-FINAL

重要な点は、最初にAdvanced Settingを開き、Source Databaseをdata-hub-FINALに変更した後にSource CollectionをMappingCustomer1に設定することです。
これは、MappingCustomer1というステップではマッピングの結果をdata-hub-FINALへ格納していますが、デフォルトの設定では、Source Databaseはdata-hub-STAGINGとなっており、
Source Databaseを変更すると、Source Collectionの設定が初期化されてしまうためです。
これらの手順によって、下図のようにカスタムステップが追加されました。

AddTripleCustomer1というステップをクリックすると、表示されている項目はModules Database とCustom Module URIだけです。
Modules Databaseは変更することはできません。Custom Module URIは変更することができますが、デフォルトでは、
/custom-modules/custom/カスタムステップ名/main.sjs
となっています。これはData Hubのプロジェクトディレクトリの下の、
src/main/ml-modules/root/custom-modules/custom/カスタムステップ名/main.sjs
というファイルに対応しています。このファイルの中にカスタムステップで実行する処理を書いていくことになります。
ここでは、3つのトリプルを挿入するコードを追加します。具体的には92行目と95行目の間にトリプルの追加処理を挿入します。

変更前 92   //insert code to manipulate the instance, triples, headers, uri, context m    etadata, etc.

93

94

95   //form our envelope here now, specifying our output format

96   let envelope = datahub.flow.flowUtils.makeEnvelope(instance, headers, trip    les, outputFormat);

変更後 92 //insert code to manipulate the instance, triples, headers, uri, context metadata, etc.

93   var sem = require(“/MarkLogic/semantics.xqy”);

94

95   let introBy = instance.Customer.introducedBy;

96   let name = instance.Customer.Name;

97   if (introBy != null){

98     let introId = fn.head(cts.uris(null, null, cts.jsonPropertyValueQuery(“Id”, introBy)));

99     if (introId!=null){

100       let triple = sem.triple(sem.iri(id), sem.iri(“introducedBy”), sem.iri(introId));

101       triples.push(triple);

102     }

103   }

104

105   triples.push(sem.triple(sem.iri(id), sem.iri(“http://www.w3.org/2000/01/rdf-schema#label”), sem.iri(name)));

106   triples.push(sem.triple(sem.iri(id), sem.iri(“http://www.w3.org/1999/02/22-rdf-syntax-ns#type”), sem.iri(“http://xmlns.com/foaf/0.1/Person”)));

107

108

109   //form our envelope here now, specifying our output format

110   let envelope = datahub.flow.flowUtils.makeEnvelope(instance, headers, triples, outputFormat);

上記の処理を簡単に説明します。
変更コード
92 //insert code to manipulate the instance, triples, headers, uri, context metadata, etc
カスタムモジュール内でドキュメントのエンベロープの各要素や、コレクション、パーミッション等のメタデータを操作する場合には、この部分にコードを挿入します。

以下ではinstance triples  headers という変数名でそれぞれインスタンス、トリプル、ヘッダーにアクセスできます。

93 var sem = require(“/MarkLogic/semantics.xqy”);
セマンティックAPIを使用するために設定します。
95-96 let introBy = instance.Customer.introducedBy;

let name = instance.Customer.Name;

各ドキュメントのインスタンスの情報がinstanceという変数に入っています。ここでは、その中にあるCustomerのintroducedByおよびNameプロパティをそれぞれintroBy、nameという変数に入れています。
98 let introId = fn.head(cts.uris(null, null, cts.jsonPropertyValueQuery(“Id”, introBy)));
cts.uris()というAPIはURIレキシコン(URIの一覧)を検索するAPIです。3番目のパラメータでどのような条件を満たすドキュメントのURIを取得するかを指定します。

ここでの条件はcts.jsonPropertyValueQuery()というクエリを使います。これは、Idプロパティの値がintroByと等しいドキュメント、つまり紹介者のIDの値をIDとして持つドキュメントを探し、そのURIを取得します。このとき返されるURIは一つではない可能性があるため(この例では1つですが、一般には複数ある可能性があります)、結果はSequenceで帰ってきます。ここではその先頭の一つを取得するためにfn.head()というAPIを使用しています。

100-101 let triple = sem.triple(sem.iri(id), sem.iri(“introducedBy”), sem.iri(introId));

triples.push(triple);

sem.triple()はトリプルを生成するAPIです。最初の3つのパラメータで、それぞれ主語、述語、目的語を指定します。ここでは、主語としてid (idには現在処理をしているドキュメントのURIが入っています)、述語として“introducedBy”という関係、目的語として98行目で取得した紹介者情報を含むドキュメントのURIを指定しています。

紹介者がいない場合には、トリプルは生成しません。

triplesというトリプルを含む変数はArray型ですので、push()を使用してトリプルを追加します。

105-106 triples.push(sem.triple(sem.iri(id), sem.iri(“http://www.w3.org/2000/01/rdf-schema#label”), sem.iri(name)));

triples.push(sem.triple(sem.iri(id), sem.iri(“http://www.w3.org/1999/02/22-rdf-syntax-ns#type”), sem.iri(“http://xmlns.com/foaf/0.1/Person”)));

この2つのトリプルは、後ほどGroveで表示する際に使用します。それぞれUI上のノードの名称とアイコンを変更するために使用されています
110 //form our envelope here now, specifying our output format

let envelope = datahub.flow.flowUtils.makeEnvelope(instance, headers, triples, outputFormat);

datahub.flow.flowUtils.makeEnvelope ()はDHFが提供するAPIで、指定したインスタンス、ヘッダー、トリプルを使ってエンベロープを作成します。outputFormatでJSONまたはXMLを指定することができます。

この変更を行ったのちにManage Flowsの画面で、REDEPLOYボタンをクリックし、フローを再デプロイしてください。
再デプロイが完了した後に、このAddTripleCustomer1ステップを実行すると以下のように3つのトリプルがドキュメントに挿入されているのが分かります。

トリプルを使用したUIアプリケーションの説明に移る前に、追加作成したトリプルに対していくつかのSPARQLクエリを実行してみましょう。

a. Labelが松本杏奈であるドキュメントのURI:

select * where { ?s <http://www.w3.org/2000/01/rdf-schema#label> <松本杏奈>.}

[{"s":"</customer/customer1/0c303ad3-eb59-40e9-90dd-074790914a44.json>"}]

b. 松本杏奈を紹介した人のドキュメントのURI:

select ?o where 
{ ?s <http://www.w3.org/2000/01/rdf-schema#label> <松本杏奈>. 
               ?s <introducedBy> ?o               }
[{"o": "</customer/customer1/13ffa18c-885a-4ba9-b8ec-71ce23b07233.json>"}]

c. 松本杏奈を紹介した人の名前(Label):

select ?name where 
{ ?s <http://www.w3.org/2000/01/rdf-schema#label> <松本杏奈>. 
            ?s <introducedBy> ?o.
?o <http://www.w3.org/2000/01/rdf-schema#label>  ?name }

 [
{
"name": "<佐藤美咲>"
}
]

d. 松本杏奈を紹介した人を紹介した人:

select ?name where 
{ ?s <http://www.w3.org/2000/01/rdf-schema#label> <松本杏奈>. 
               ?s <introducedBy>+ ?o.
?o <http://www.w3.org/2000/01/rdf-schema#label>  ?name }

[
{"name": "<佐藤美咲>"}, 
{"name": "<田中一郎>"}
]

dのクエリは、<introducedBy>+と、最後に+を付けることで、関係をたどっていますが、トリプルだけのクエリでは実際にはこのような限定的なことしかできません。
MarkLogicはドキュメントとトリプルさらには構造化データを一つのデータベースの中で組み合わせて使用することで検索、つまり探すことの範囲を広げます。

2の「Groveの詳細ページにおいてドキュメントの内容とともに、作成したトリプルを表示するようなUIを作成する
ステップは次回の記事でご紹介します。

太田佳伸

MarkLogic以前は、RDB、ORDB、ObjectDB、サーチエンジン、XMLDB等々のベンダーでエンジニア、エバンジェリスト、テクノロジスト等を経験してきました。
最近はPoCや新しい機能の調査を担当しています。
平日はMarkLogicのServerSide JavaScript、休日は高校生にC /C++等々のロボットプログラミングを教えています。

著者が作成したブログ

関連タグ

Prefooter Dots
Subscribe Icon

Latest Stories in Your Inbox

Subscribe to get all the news, info and tutorials you need to build better business apps and sites

The specified form no longer exists or is currently unpublished.