前回は、Meteorのデータベースアーキテクチャを説明しました。Meteorがサーバデータをクライアントにキャッシュすることで、クライアントでもサーバでも同様のAPIを用いることができるため、クライアントとサーバのコード共有が最大限に促進されます。
では、今回はMeteorのデータベースAPIを紹介していきたいと思います。ただし字数の都合上、全てのAPIを紹介することはできません。完全なリストはMeteorの公式ドキュメントを参照してください。
また、MeteorのデータベースAPIはMongoDBを理解していると、より理解が促進されます。ちょうど、gihyo.jpでも連載記事があるようなので、参照することをお勧めします。
また、前回使用したサンプルに機能を追加して、データの追加・更新・削除を行えるようにしたサンプルを用意しました。
上部のフォームに値を入力して「追加」ボタンを押すと、データベースに値が追加されます。一覧のチェックボックスを選択すると、上部のフォームに値が読み出されます。そのまま値を修正して更新を行うことができます。また、チェックした行のレコードをまとめて削除することができます。
こちらのサンプルは、コード量が多少かさんでしまったので、サンプルの全文は掲載しません。以下からダウンロード可能にしておきますので、必要に応じて参照してください。
サンプル8-1(sample8-1.zip)のダウンロードはこちらから
コレクション
前回もご説明した通り、データベースに格納するオブジェクトの集まりを「コレクション」と呼びます。一つのコレクションには任意のJavaScriptオブジェクトを格納できますが、通常、同様のプロパティを持つ同じ型のオブジェクトを格納します。また、MongoDBではコレクションに格納するオブジェクトのことを「ドキュメント」と呼び表しますので、以下それに従います。
new Meteor.Collection(name, options)
コレクションを生成するためのコンストラクタです。第一引数にはコレクションの名前を表す文字列、第二引数にはオプションを指定します(オプションについては、ここでは説明しません)。nameを省略すると、サーバ・クライアント間での同期が行われないコレクションとなります。
サンプルにおいては、従業員データを格納するためのコレクションをemployees
という名前で作成しています。
find(selector, options)
コレクション内で、条件に合致するドキュメントを検索して返します。検索条件は、第一引数のselector
で指定します。たとえば、ID(_id
プロパティ)の値が一致することを表す条件は以下のようになります。
複数のプロパティが一致する条件を指定することもできます。
また、値の大小に基づく比較条件や条件の否定(NOT)なども行うことができます。
検索条件を指定しない(すべて取得する)場合には、空のオブジェクトを指定します。
その他にもたくさんの条件指定方法があります。詳しくはMongoDBの公式リファレンスを参照してください。
第二引数には、以下の様なプロパティを持つJavaScriptオブジェクトを指定します。
sort…ソートの指定。ソートするプロパティの順序を配列で指定します。
skip…結果をスキップする件数
limit…最大の取得結果数
fields…結果に含めるフィールド(サーバ上でのみ有効)。結果に含めるプロパティには1を、含めないプロパティには0を指定します。
reactive…結果をリアクティブとするかどうか。デフォルトはtrue(リアクティビティについては、後の連載記事をお待ちください)
サンプルにおいては、テンプレート内の変数employees
の値として、関数の戻り値に指定しています。
返却されるオブジェクトは、検索結果を辿ることのできるカーソル(Meteor.Collection.Cursor
)です。カーソルには以下のようなメソッドが定義されています。
forEach(callback)…先頭から順にドキュメントを処理します。以下のように使用します。
map(callback)…カーソルの内容から、新たな配列を生成します。配列の要素は、コールバック引数の戻り値で構成されます。
fetch()…カーソルから全てのデータを読み込み、配列を返します。
count()…検索結果の総数を返します。
rewind()…カーソルを初期状態に戻します。
observe(callbacks)…カーソルの状態を監視します。以下の利用法を見てください。
findOne(selector, options)
検索結果の1件目を取得して返します。find(selector, options).fetch()[0]
と同様です。サンプルにおいては、一覧のチェックボックスをチェックされた際、DBからオブジェクトを読みだして入力フォームにセットする処理で使用しています。
insert(doc, callback)
コレクションにドキュメントを追加します。
第一引数のドキュメントには、_id
プロパティを含めてはなりません。同プロパティは、MongoDBによって自動的に生成されます。
第二引数は処理が完了した際に呼び出されるコールバックです。サーバ上では、このコールバックを省略すると、処理が終了するまでメソッド呼び出しがブロックします。サーバ上であってもコールバックを引数に指定した場合、もしくはクライアント上で呼び出した場合は、メソッド呼び出しがブロックすることはありません。
メソッドの戻り値は、新たに生成されたID文字列です。
サンプルにおいては、「追加」ボタンをクリックされた際に、insert()
メソッドを使用してデータを追加しています。
update(selector, modifier, options, callback)
コレクション内のドキュメントを更新します。引数selector
で更新対象を絞込み、modifier
で更新方法を指定します。
selector
の指定方法は、find()
におけるものと同様です。modifier
の指定方法の例を幾つか挙げます。完全なリストはMongoDBの公式リファレンスを参照してください。
プロパティに値をセットするには$set
モディファイアを指定します。
数値プロパティの値を増減させるには、$inc
を指定します(マイナス値も指定可能)。
上記のような$
プロパティを持たないオブジェクトを指定すると、オブジェクトの完全な入れ替えとなります。サンプルでは、更新ボタンを押した際の処理として、update
メソッドを使用しています。
第三引数のoptions
に、multi
というプロパティに真偽値を指定することで、マッチしたドキュメント全てを更新するのか、一件のみ更新するのかを指定できます。デフォルトは{ multi: false }
(一件のみ更新)です。
最後の引数callback
には、処理が終了した際のコールバックを指定します。サーバ上で実行する際には、コールバックを省略すると同期型のメソッドとなり、処理が終了するまでブロックします。それ以外の場合はブロックしません。
remove(selector, callback)
引数selector
に合致したドキュメントを全て削除します。selector
の指定方法は、find()
におけるものと同様です。
最後の引数callback
には、処理が終了した際のコールバックを指定します。サーバ上で実行する際には、コールバックを省略すると同期型のメソッドとなり、処理が終了するまでブロックします。それ以外の場合はブロックしません。
サンプルでは、削除ボタンをクリックされた際に、チェックされた行のレコードを全て削除するためにremove
メソッドを使用しています。$in
セレクタを用いて、削除対象となるドキュメントを絞り込んでいます。
まとめ
MeteorのデータベースAPIは、MongoDBのAPIをかなり踏襲しています。そのため、MongoDBの強みである検索条件の柔軟な指定方法などをそのまま利用できるのが利点です。
次回は、今回説明しなかったデータベースAPI、そしてMeteorプログラミングの最も先進的な部分とも言える「リアクティビティ」について少し触れる予定です。