こんにちは。今回は Voyage を紹介します。
NoSQL データベースのラッパーです。
目標は、本物のアプリケーションを 構築することです。
Voyage を使って TinyBlog のように Mongo データベースに
オブジェクトを格納して、実サービスとして デプロイできるようになるでしょう。
また、オブジェクトを格納するための
簡単な方法もお見せしたいと思います。
Voyage は簡単なソリューションです。
まず、MongoDB とは何でしょうか？
Mongo はドキュメント指向の 新しい NoSQL データベースです。
強力な問い合わせ言語を持っています。
Mongo はまた CouchDB や Riak に並んで 最も人気のあるデータベースの 1 つです。
Mongo と Voyage を使いましょう。
実際のところ、Voyage はマッパーです。 オブジェクトに対して プログラマに代わって
MongoDB にほぼ自動的にマップします。
Java で Hibernate を使ったことがあれば
Voyage は MongoDB での Hibernate と同等です。
ただし Voyage は Pharo 用に作られています。
ここに Voyage の特徴を挙げています。 とても単純です。
格納されたオブジェクトを読み込んだ時に 元のオブジェクトの同一性が保証されています。
エラー処理も提供されています。
そしてコネクションプールを実装しているので
スピードも向上しています。
簡単なところから始めましょう。
最初に MongoRepositoryを作ります。
これらの表現式を使います。
Mongo データベースに アクセスしたいとします。
Mongo は Pharo の外部で 管理されているわけですが
プロトタイプする時にはよく
Mongo データベースをオンメモリで使います。
ここでは MongoMemoryRepository として参照されています。
Mongo データベースは必要ありません。 まず最初に、アプリケーションをプロトタイプします。
プロトタイプがちゃんと動くようになったら オンメモリのレポジトリを
本物のレポジトリに切り替えて 外部にあるデータベースを使います。
こうやって作っていきます。
Mongo を説明するために
とても単純なモデルを用意しました。 スーパーパワーを持ったスーパーヒーローがいて
鎧や武器を持っています。
このコースでお見せすることを使って 演習をすることができるでしょう。
きっと助けになります。
スーパーマンをスクリプティングすることを 楽しんでください。
まず、どうやってヒーローとパワーを操るかを 見てみましょう。
まず Hero クラスがあります。 Hero クラスには名前とレベルと能力があります。
名前にはアクセサーとセッターがあります。
レベルについても同様です。
能力(power)は集合として管理します。
能力がなければ空集合です。
何か能力を加える時には それを集合に加えます。
これがとても基本的な部分です。
当面は能力には名前だけがあります。
名前を書くこともできますし 書かないでおくこともできます。
さて、ここでのポイントは ドメインクラスがデータベースに格納される
ことをどうやって宣言するかです。
ルートクラスという考え方を理解することが このデータベースの出発地点です。
システムのどのクラスでも構いません。 ルートとして印を付けて
isVoyageRoot というクラスメソッドがあれば。 （クラスメソッドですよ）
Hero クラスの場合には isVoyageRoot は true を返します。
この時点で Voyage は Hero を
Mongo データベースに格納するとわかります。
スパイダーマンをやってみましょう。
名前は Spiderman で レベルは epic（最高）です。
能力は、スパイダーマンの特殊技能ですが 彼の能力は強靭なこと、壁を登ること
蜘蛛としての本能を持っているとされています。
この情報を保存します。
save は Voyage にこのスーパーヒーローを
データベースに格納するように指示します。
同じことをウルヴァリンと 彼の能力について行って
そのデータを保存します。
さて、Mongo データベースを見ると
db.Hero.find すると
スパイダーマンと
彼の能力を見ることができるはずです。
ここで気を付けてください。
彼の能力はここに全て示されています。
ウルヴァリンも同様です。
これができたら、Pharo で沢山のことができます。
詳しくは説明しませんが スーパーヒーロー全員を選んでくると
スパイダーマンとウルヴァリンが得られます。
スパイダーマンを見つけるように 言うこともできます。
レベルが epic (最高) のスーパーヒーロー 全員を見つけてくるように言うこともできます。
すると 2 人のスーパーヒーローが得られます。
違う表現もできます。
実際、Mongo データベースは
JSON を扱うことができます。 つまり JSON を実行中に作って
保管したり JSON 形式での問い合わせができます。
どのスーパーヒーローが スパイダーマンという名前か
知りたいとしましょう。
JSON 形式で辞書として表現したので 1 つのエントリが得られます。
同様に selectMany: することもできます。
問い合わせを表現するのに最も簡単な 方法が何かによるわけですが
それは今の所は大事ではありません。
もっと高度な問い合わせもできます。
ヒーローを全員選んだり
あるいは 最高レベルのスーパーヒーローを 複数選ぶことができます。
名前で昇順に並べることができます。
リミットを 10 に設定した 0 ページ目から 開始することもできます。
するとデータベースから区画ごとに 取り出すことができます。
これらのことをしたい時には ドキュメンテーションを読んでください。
他の操作もあります。 例えば、スーパーヒーローの数を数えるなど。
ある特定の性質を持つものだけを数えることができます。
削除することもできます。 全て削除したら、データベースが空になります。
このコマンドには気を付けてください。
ここで、1項目選択して それを削除することができます。
このヒーローはデータベースから削除されます。
これらの操作をすることができます。
さて、MongoDB を使っていると 出てくる疑問があります。
Mongo ではベースルートとは何でしょう？
クラスはいつルートと定義されるのでしょう？
答えは、問い合わせたいクラスが ベースルートです。
それが第 1 のルールです。
あるクラスをルートと定義するのは
そのクラスの全てのオブジェクトに アクセスしたいからです。
別の理由としては ルート間でオブジェクトを共有したい
という場合です。
Power を共有したい
ヒーロー間で能力を共有できることを 明確にしたい場合には
Power (能力) をルートとして定義します。
これを見てください。
この例では、Hero はルートです。
そして Power もルートです。
Voyage では、どんなクラスもルートとして 宣言することができます。
やり方はこうです。
Power クラスは isVoyageRoot となっています。
さて、Fly（飛行）という能力を作って
保存します。これでデータベースに格納されます。
強靭（Super strength）も同じです。
ここで Voyage に飛行能力を取り出すように
問い合わせることができます。
また、超人的な強靭さの能力も 取り出したい。
そしてここで、スーパーマンを作ります。
Voyage に伝えている意味は
ここに 2 つの能力があって、（このヒーローは） システムに1つしかないものだから、それを保存する。
基本的なスキーマが変更されるたびに
データベースをリセットして
ちゃんと動くようにします。
ここでどうなっているかを見せます。
スーパーマンの能力は 前と違う形で表現されています。
能力はヒーローの中に埋め込まれていません。 能力への参照になっています。
つまり、飛行能力を持つ他のヒーローがいる ということです。
2 つの Power のインスタンスがあるのではなく 共有されています。
つまり、ドメインによって、また それをどうモデル化するかによって
ルートの定義は異なってきます。
この単純な例で考え方を理解してください。
実際、繰り返しますが ドメインルートを定義するのは
それに対して問い合わせをしたり オブジェクトを共有する場合です。
Voyage では関連は
関係データベースでの外部キーと 同じように表現されています。
Voyage はルートオブジェクトの循環参照を 自動的に扱うことができます。
しかし気を付けてください。 Voyage は埋め込まれたオブジェクト間の
循環参照はサポートしません。
実験してみてください。 ルートであれば安全です。
このコースでは、Mongo データベースに オブジェクトを格納することが
とても簡単だということをお見せしました。
もっと知りたい場合には Enterprise Pharo: a Web Perspective
を読んでください。 この MOOC の資料に入っています。
スーパーヒーローデータベースを構築する ちょっとしたチュートリアルを参照できます。
それで全て学ぶことができます。