No.17 柔軟なデータ構造を扱えるCorticon (Corticon Studio編)
2017.07.11 Progress Corticon
本エントリーは株式会社アシスト様が寄稿したエントリー(https://www.ashisuto.co.jp/product/category/brms/progress_corticon/column/detail/brmstech17.html)を転載したものとなります。
|
Corticonは、Corticonとの連携を求めるアプリケーションの形態を問わないよう、SOAPやRESTという一般的な手段で接続できるように設計されています。そこで重要なのが受け渡すデータの構造になりますが、Corticonでは、ふたつのXML構造を取り扱うことができます。
XMLというと階層型(親子関係を示すような)が一般的ですが、Corticonでは階層型とともにフラット型のXML構造を取り扱えるのが特徴になります。
今回のコラムでは、そのふたつの構造が使えるCorticonのメリットについてお伝えします。
はじめに、階層型XMLとは、例えばつぎのようなものです。(※)
- ※説明のために簡略化したXMLです。
<階層型XML例1>
<EntityA >
<EntityB>
<value>ほげ1</value>
</EntityB>
<EntityB>
<value>ほげ2</value>
</EntityB>
</EntityA>
<EntityA>
<EntityB>
<value>ふが1</value>
</EntityB>
<EntityB>
<value>ふが2</value>
</EntityB>
</EntityA>
EntityA内にEntityBが格納されています。また、EntityAとEntityBは親と子の関係にあり、一つのEntityAに対して複数のEntityBがあるため、EntityAとEntityBはツリー状の一対多の関連性になっています。階層型のXMLの場合、エンティティ間の親子構造が直感的でわかりやすく、XMLをパースするプログラムでも取り扱いやすい形式です。
ところが、このような階層型XMLには問題点があります。上の例のような単純な一対多の関連性のデータの場合はよいですが、多対多の関連性のデータの場合は表現できません。例えばつぎのようなXMLです。
<階層型XML例2>
<EntityA>
<EntityB>
<value>ほげ1</value> <―①
</EntityB>
<EntityB>
<value>ほげ2</value> <―②
</EntityB>
</EntityA>
<EntityA>
<EntityB>
<value>ほげ1</value> <―①
</EntityB>
<EntityB>
<value>ほげ2</value> <―②
</EntityB>
</EntityA>
<階層型XML例1>と似ていますが、上のXML例の<―①や<―②のようにEntityBの値「ほげ1」, 「ほげ2」が上と下で重複しています。
<階層型XML例2>で本来表現したかった状態は、上のEntityAに格納されている二個のEntityBが、下のEntityA内にも格納されている、という状態です。複数のEntityAに対して複数のEntityBがある、多対多の関連性を表現しようとしています。
しかし、<階層型XML例2>のようなツリー状態だと、別階層の同じ値を持ったEntityBが、同じオブジェクトなのか偶然同じ値をもっただけの別オブジェクトなのか、論理的に区別がつきません。
実際、Corticonのルールで<階層型XML例2>が処理される際は、上のEntityBふたつと下のEntityBふたつは、それぞれ同じ値をもっただけの別のオブジェクトとして扱われます。
この問題を解決するために、Corticonでは階層型XMLだけではなく、フラット型XMLも入出力として取り扱うことができます。(※1)
今回の記事では、Corticon Studioを使用して、語彙に多対多の関連性を設定しテスト時にフラット型XMLの入力データを作成する方法を、ご紹介します。(※2)
- ※1 Corticonで取り扱うことができるJSON形式の入出力にも、フラット型と階層型がありますが、本記事では解説しません。
- ※2 Corticon Serverのディシジョン・サービスに対してクライアントプログラムからリクエストを行う際に、階層型/フラット型のXMLを使い分ける 方法は、次回の記事で解説します。
[記事執筆環境]
Corticon Studio 5.5.2.7
ルールの実装
今回の記事で使用するサンプルルールをCorticon Studioで作成します。
■ 語彙(ecore)
今回の記事で使用する語彙(ecore)は以下です。
<語彙の設定表>
エンティティ名 | XML要素名 | |
買い物かご | Cart | |
属性名 | XML要素名 | 型 |
商品数 | numItems | 整数 |
合計金額 | totalPrice | 整数 |
関連性名 | XML要素名 | カーディナリティ, 関連方向性 |
商品 | Items | *->*, 双方向 |
エンティティ名 | XML要素名 | |
商品 | Item | |
属性名 | XML要素名 | 型 |
商品名 | Name | 文字列 |
価格 | Price | 整数 |
関連姓名 | XML要素名 | カーディナリティ, 関連方向性 |
買い物かご | Carts | *->*, 双方向 |
<作成した語彙のCorticon Studioでの表示 >
|
商品の視点で見ると、異なる買物かごにそれぞれ入る場合があり、買物をする側から見ると、買物かごに異なる商品がいくつか入ることをイメージしています。買物かごも商品も複数あり、それぞれが多対多になっているイメージです。同じ多対多の構造を、もしRDBMSで設計するとならば、つぎのようなER図になります。
<RDBMSでのER図例>
|
Corticonの語彙で多対多の関連性を作成する際には、上記のER図例の中心にあるような「関連性テーブル」は必要ありません。
関連性の作成時に関連ダイアログでソースエンティティに「多」, ターゲットエンティティも「多」を選ぶだけです。
<関連ダイアログ>
|
■ルールシート(ers)とルールフロー(erf)
ルールは以下の検証用のルールシート(ers)が1つだけです。
<ルールシートのスコープと条件とアクション>
|
これはそれぞれの買物かごに入った商品の個数と合計金額を出すルールです。
条件に「すべての買物かごのすべての商品(allItem)の種類数が3未満の場合はそのまま合計し、3以上の場合は合計金額を半額にする」というルールが入っています。
ルールシート(ers)を作成したら、このルールシートだけが入ったルールフロー(erf)を作成します。
ルールテストで階層型XMLとフラット型XMLを入力する
ルールフロー(erf)に対するルールテスト(ert)を作成しテストを行います。
このテストに対する入力が、階層型XMLかフラット型XMLかで、ルールの動作が変わります。
■階層型の場合
ルールテストで入力データを作成する際に、通常(※)はつぎの<階層型XMLの入力と出力>のテストデータになります。
- ※Corticon Studio画面の左の語彙ペインから、必要な語彙ツリーをルールテストの入力欄にドラッグ&ドロップして、入力値を作成する方法
<階層型XMLの入力と出力>
|
入力値の実体であるXMLテキストデータは、Corticon Studioメニューの「ルールテスト」-「テストシート」-「データ」-「入力」-「要求をXMLでエクスポート」で確認することができます。
上記テストの入力をエクスポートし、テキストエディタなどで確認するとつぎのようになっています。
<階層型XMLの入力データの内部>
<WorkDocuments>
<Cart id="買物かご_id_1">
<totalPrice xsi:nil="true" />
<numItems xsi:nil="true" />
<Items id="商品_id_1">
<price>100</price>
<name>バナナ</name>
</Items>
<Items id="商品_id_2">
<price>200</price>
<name>りんご</name>
</Items>
</Cart>
<Cart id="買物かご_id_2">
<totalPrice xsi:nil="true" />
<numItems xsi:nil="true" />
<Items id="商品_id_3">
<price>100</price>
<name>バナナ</name>
</Items>
<Items id="商品_id_4">
<price>200</price>
<name>りんご</name>
</Items>
</Cart>
</WorkDocuments>
このXMLは階層型XMLで一対多の関連性のデータです。語彙作成の段階では「買物かご」と「商品」は多対多の関連性を設定していますが、Corticon Studioの標準的な手順で作成した入力データは、ルールへの入力値が自動的にこのような階層型XMLになります。
したがって、本記事の冒頭で解説したように、商品[1]商品[3]のバナナと商品[2]商品[4]のりんごは、同じオブジェクトではなく同じ値を持っただけの別オブジェクトとして扱われます。結果として、テストの出力を確認すると、買物かごの合計金額がそれぞれ300円となるべきところを、買い物かごには全部で4つの商品が入っていると判定して合計金額が300円の半額(150円)となっています。
■フラット型の入力値
語彙で設定した多対多の関連性を生かすには、入力値にフラット型XMLを作成し、多対多の関連性を持ったデータにする必要があります。
具体的なテストシートでの操作は以下です。
(1)ルールテストの「入力」に関連性を持たない状態のエンティティを並列に作成する。
►ここでは関連性を持たない「買物かご」と「商品」エンティティを入力欄に並列に作成する。
►<図1>の入力欄
(2)右側の「ルール語彙」ペインから、目的の関連性を「Ctrl」ボタンを押しながら入力欄のエンティティに
ドラッグ&ドロップする。
►ここでは左の「買物かご」内の「商品(商品)」を「Ctrl」ボタンを押しながら右の「買物かご[1]」にドラッグ&ドロップする。
►<図1>のオレンジの線
<図1>
|
(3)関連ダイアログが表示されるので、関連させたいエンティティを選択し「OK」ボタンを押す。
►ここでは「商品[1]」を選んで「OK」を押す。<図2>
►入力欄が<図3>の状態になる。
<図2>
|
<図3>
|
(4)同様の手順を繰り返し、関連性が設定された入力値を作成する。
►ここでは<図4>の入力欄になるように作業を行った。
(5)テスト実行を行う。
►<図4>の出力欄
<図4>
|
<図4>の出力欄を確認すると、商品の種類は全部で2種類のみしかないと判定された結果、合計金額は半額にはなっておらず、ふたつの商品がそのまま合計されていることがわかります。
階層型XMLの確認時と同様に、入力のXMLを確認するとつぎのようになります。
<フラット型XMLの入力データの内部>
<WorkDocuments>
<Cart id="買物かご_id_1">
<totalPrice xsi:nil="true" />
<numItems xsi:nil="true" />
<Items href="#商品_id_1" />
<Items href="#商品_id_2" />
</Cart>
<Cart id="買物かご_id_2">
<totalPrice xsi:nil="true" />
<numItems xsi:nil="true" />
<Items href="#商品_id_1" />
<Items href="#商品_id_2" />
</Cart>
<Item id="商品_id_1">
<price>100</price>
<name>バナナ</name>
</Item>
<Item id="商品_id_2">
<price>200</price>
<name>りんご</name>
</Item>
</WorkDocuments>
Corticonで使用する多対多の関連性を持ったフラット型XMLの内部はこのようになっています。
各エンティティは階層型XMLのようにツリー構造にはなっておらず、全てフラットに並んでいます。エンティティ間の関連性はリンク(href)で表現されています。リンクの参照元になっているのは各エンティティに付加されているID情報です。このため、階層型XMLに比べて視認性は下がりますが、正確な多対多の関連性が表現できます。
また、入力の内容にもよりますが、多対多の関連性のフラット型XMLは、複数回現れるエンティティがひとつのエンティティで表現できるため、一対多の関連性の階層型XMLに比べて、格納されているエンティティ数が少なくなる傾向があるのも特徴です。今回の例では、階層型XMLは「商品」エンティティを4個作成していたのに対して、フラット型XMLの「商品」エンティティは2個だけで済んでいます。
まとめ
今回は、Corticon Studioで多対多の関連性とフラット型XMLを取り扱う方法をご紹介しました。
階層型XMLと比較して、フラット型XMLのメリットとデメリットをまとめると、以下のようになります。
●フラット型XMLのメリット
►階層型XMLでは表現できない多対多の関連性を表現できる
►多対多の関連性にした結果、階層型XMLに比べてデータ量が少なくなる傾向がある
●フラット型XMLのデメリット
►Corticon Studioでデータを作成する際に少しコツが必要
►XMLの視認性が下がる
►XXMLパースプログラムでの取り扱いに工夫が必要
Corticonでは、多対多の関連性をシンプルな一対多の関連性で代用できることが多いです。また、階層型XMLのほうがStudioでの操作もServerでの送受信でも取り扱いやすい形式です。そのため、実際のルール開発時に、多対多の関連性とそれを表現したフラット型XMLをあえて使用しないといけない場面は、あまりありません。
しかし、多対多の関連性はRDBMSのテーブル設計ではよくある構造なので、入力値がRDBMS由来のものである場合は、Corticon内でも多対多の関連性のまま取り扱うほうが自然な場合があります。そのような場合は今回紹介したフラット型XMLを使用すると良いでしょう。
また、多対多の関連性(フラット型XML)のほうが1対多の関連性(階層型XML)より格納されているエンティティ数が少なくなる傾向があります。少しでも送受信するデータ量を少なくしたい場合などもフラット型XMLの使用を検討してみてください。
次回は、Corticon Serverのディシジョン・サービスに対してクライアントプログラムからリクエストを行う際に、階層型/フラット型のXMLを使い分ける方法に関して解説します。
著者紹介
|
情報基盤技術統括部 プログレス推進部 |