この三部作の最初のエピソードでは、リストボックス、エンティティ、エンティティ選択を使って、ORDAの基本を示しました。今日は、再帰的な関係を利用するいくつかのクエリを実行することで、もう少し深く掘り下げていきます。また、「meta info expression」プロパティを使用して、リストボックスをきれいに表示する方法についても簡単に説明します。
ユースケースシナリオ
非常に大きなリストから一人を選択し、その両親と祖父母を探したいのです。兄弟姉妹も知りたい……子供がいればその子も!叔父や叔母、そしていとこも……?
そんなことをやっていたら、いつまでたっても終わらない。やってみましょう。
はじめに
People エンティティは、1960年1月1日以降に生まれた人を選択し、Formオブジェクトの中に保存されます。
Form.people:=ds.PEOPLE.query("誕生日>=:1";!1960-01-01!).orderBy("誕生日 asc, Lastname asc, Firstname asc")
この推奨クエリ形式では、プレースホルダ(:1)とパラメータ(!1960-01-01!)を使用しています。
リストボックスのセットアップ
前回の記事で見たように、エンティティ選択(Form.people)は、エンティティ選択プロパティとして最初に設定されます。
エンティティ選択を元にしたリストボックスには、いくつかの新しいプロパティがあります。そのうちの3つを説明します。現在の項目、選択された項目、メタ情報表現です。
現在の項目と選択された項目は、ユーザーがリストボックスの選択を変更したときに、自動的に更新されます。
現在の項目には、選択されたエンティティ(複数選択されている場合は、最後に追加されたもの)が含まれます。リストで選択されている項目がない場合、このエンティティはnullになります。
選択された項目は、選択されたエンティティです。選択された方法(shift+クリック、control+クリックなど)に関係なく、リスト内のすべての選択された項目が含まれます。この選択項目は常に存在しますが、空にすることもできます。
Meta info式については、この記事の最後に記載しています。
家族メンバー
メインリストボックスの選択変更イベントで、選択された人の親、子、兄弟を見つける必要があります。
Formparents:=GetParents ( . ) .:=GetChildren ( . ) Formpersons
FormchildrenFormpersons
Form .:=GetSiblings ( .siblingsFormpersons
)
このようにエンティティセレクションを作成すれば、祖父母、叔父、叔母、そして従兄弟を探すのは実に簡単です。祖父母は親の親、おじとおばは親の兄弟、そしていとこはおじとおばの子なのです!
FormgrandParents:=GetParents ( . ) .:=GetSiblings ( . ) Formparents
FormauntsAndUnclesFormparents
Form .:=GetChildren ( . )cousinsFormauntsAndUncles
クエリ
ORDA を使用すると、関連するメンバの検索が非常に簡単になります。各「Get」メソッドは、エンティティセレクションをパラメータとして受け取り、別のエンティティセレクションを (コンテンツまたは受け取ったものに基づいて) 返します。
両親
GetParentsメソッドはForm.parents を $1 パラメータとして受け取ります。これを$_persons と名付けましょう。
(アンダースコアは、”エンティティ “と “エンティティ選択 “を簡単に区別するための視覚的な補助としてのみ使用されています)。
念のためですが、Motherと Fatherは関係定義で定義されたエンティティです。これらは「N対1」の関係の名前である。
ORDAのマジックは、単一のエンティティ($person)で使用した場合は単一のエンティティ($person.Mother, $person.Father, $person.Partner) を、別のエンティティ選択($_persons)で使用した場合はエンティティ選択を返すことができるということです。
$_persons:=$1
$_parents:=$_persons.Mother.or($_persons.Father)
$0:=$_parents
子供
1対n」の関係で定義されたエンティティ選択も同様です。
// Note: the text below fits on a single line
$_children:=$_persons.ChildrenAsFather(...)
.or($_persons.ChildrenAsMother) (...)
.orderBy("誕生日 asc")
兄弟姉妹
兄弟姉妹の場合、複数のリレーションシップを使用する必要があります。まず父親を見つけ、 次に父親の子供を見つけ、そして母親には論理的な「または」を適用し、さらに論理的な「マイナス」で兄弟姉妹のリストから人々を削除します(Paul の両親には Paul と John という息子がいますが、 Paul には John という兄弟が一人だけいます…)。
// Note: the text below fits on a single line
兄弟姉妹:=$_persons.父ChildrenAsFather(...)
.or($_persons.Mother.ChildrenAsMother)(...)
.minus($_persons)
最終結果
さて、カテゴリー別に家族のメンバーが見つかったので、他のリストボックス(メインのリストボックスと同じ種類の情報を持つ)に表示することにします。あとはリストボックスを複製して、そのエンティティセレクションプロパティ名を Form.grandParents, Form.parents, Form.siblings, Form.children, などに変更するだけです。
メタ情報表現
Metainfo 式は、4Dメソッドで、(通常は) Thisを最初のパラメーターとして受け取り、オブジェクトを返します。上の写真では、このメソッドを使って、青とピンクの行の背景を描いています。
返されたオブジェクトは、ここで定義されたいくつかのプロパティを持っています。この場合、使用するプロパティはfillのみです。
$person
:=$1
$meta :=New object()
$even :=($person.indexOf()%2)=0)// is it an even or and odd row ?
If ($person.Gender=True)// women If ($even)
$meta .fill:="#fff0f0"// women light
Else
$meta .fill Else End if:="#ffe8e8" // women a bit darker
End if
Else // man
If ($even)
$meta fill :="#e8f8ff"// men light
$meta fill :="#e0f0ff"// men a bit darker
End if
$0:=.$meta
まとめ
このデータベースは基本的に 7 行のコードで構成されています!
最初のクエリで Form.people を満たし、6 つの“Get…” メソッドの中で 1 行のコードを書いています。シンプルで強力です。
では、なぜ何かを忘れているような気がするのでしょうか?そうそう……速いんでしょうか?何千人もの人がいるグループの中で、一人の人が6つのカテゴリーの親族を見つけるのにかかる平均時間は約1ミリ秒です(iMac 4.2Ghz Core i7 16Gbでテスト済み)。
もし、選択された人々がもっと大きい場合(例えば、7284人)、平均時間は 6ミリ秒になります。
ご自身で試してみてください。デモをダウンロードして、ORDAをお楽しみください !