このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

MongoDBにおけるJavaScriptの利用

MongoDBでは、dbがデータベース、collがコレクションだとして、db.coll.find(<クエリ式>) によって問い合わせが行えます。クエリ式として、JavaScriptの関数をそのまま渡すことができます。例えば、db.coll.find(function(){return this.a == 3;}) のように。

JavaScript関数には、コレクション内のドキュメント(オブジェクト)が順に渡されますが、引数ではなくてthisとしてドキュメントが渡されます。述語(boolean値関数)でコレクションを絞り込む高階関数をfilterとすると、db.coll.find(fun) は、filter(fun, db.coll) と同じことです。

findの引数に文字列が渡されると、その文字列はJavaScriptの関数ボディと解釈されます。db.coll.find(str) は、db.coll.find(new Function("return " + str)) と同じです。よって、db.coll.find("this.a == 3") は、db.coll.find(new Function("return " + "this.a == 3")) となります。

以上のことを知っていれば、JavaScriptを使った問い合わせが自由にできることになります。しかし、JavaScriptは無闇に使わないほうがいいでしょう。先の例 db.coll.find(function(){return this.a == 3;}) なら、db.coll.find({a:3}) という問い合わせを使うべきです。簡略に書けるだけではなく高速です。フィールドaにインデックスが付いている場合なら、{a:3} を使った検索は格段に速いでしょう。

「フィールドaの値が3で、フィールドbの値を二乗して10未満」という条件による問い合わせは、db.coll.find(function(){return this.a == 3 && this.b * this.b < 10;}) と書けます。二乗の計算が入っているので、JavaScriptなしで検索条件を書くのは困難です。JavaScriptの使用を最小にするために次のような書き方が出来るといいのですが、これはサポートされてません。


db.coll.find(
{$and: [{a:3}, "this.b * this.b < 10"]}
)

MongoDBネイティブの問い合わせ記法とJavaScriptを混ぜて使うことは出来ないようです。ザンネン。

findの結果はコレクションではないので、db.coll.find({a:3}).find("this.b * this.b < 10") のような繰り返し検索もできません。SQLのSELECT INTOのように、検索結果をコレクションに格納する方法もないようです。それをやろうとすると、クライアント側におけるinsert操作が必要になります。

JavaScriptによりフィルタリング(絞込み)する方法は柔軟で強力ですが、コレクション内のすべてのドキュメントをJavaScript関数に通すことになるので、大きなコレクションでは効率が心配です。高速なネイティブ条件演算子JavaScript関数との(順序に依存する)AND演算が用意されてないのが痛いなー。