|
based on v117 (2010-12-01更新) - オリジナル 最初にMongoDBには多くの機能を持ったリッチなクエリーがあります。このページはその中のいくつかの機能を紹介します。 MongoDBのクエリはJSON形式で表現します。データベースに保存しているドキュメントにとても似ています。 たとえば、 // i.e., select * from things where x=3 and y="foo" db.things.find( { x : 3, y : "foo" } ); このページに出てくるオペレータはすべて同じクエリ内で組み合わすことができることに注目してください。たとえば、jが3ではなく、kが10より大きいすべてのドキュメントを探すクエリは、 db.things.find({j: {$ne: 3}, k: {$gt: 10} });
フィールドの中の一部を取得[フィールドの中の一部を取得] 参照 条件オペレータ<, <=, >, >=クエリの中で、多い、少ない、という比較のためには以下の特別な形式を使ってください。 db.collection.find({ "field" : { $gt: value } } ); // 大きい : field > value
db.collection.find({ "field" : { $lt: value } } ); // 小さい : field < value
db.collection.find({ "field" : { $gte: value } } ); // 以上 : field >= value
db.collection.find({ "field" : { $lte: value } } ); // 以下 : field <= value
例: db.things.find({j : {$lt: 3}});
db.things.find({j : {$gte: 4}});
範囲指定するために以下を組み合わせることができます。 db.collection.find({ "field" : { $gt: value1, $lt: value2 } } ); // value1 < field < value
$all$all オペレータは、 $in に似ていますが、指定した配列すべてがマッチする必要があります。例えば、 { a: [ 1, 2, 3 ] }
これは以下にマッチします。 db.things.find( { a: { $all: [ 2, 3 ] } } );
しかしこれはしません、 db.things.find( { a: { $all: [ 2, 3, 4 ] } } );
一つの配列は、 $all 条件で指定したよりも多くの要素を持つことができます。。 $all で指定したものがすべてマッチする必要があります。 $existsフィールドが存在するか(またはしないか)をチェックします。 db.things.find( { a : { $exists : true } } ); // 存在する場合オブジェクトを返します。
db.things.find( { a : { $exists : false } } ); // 存在しない場合
$mod$mod オペレータは、where条件の中で、余りを速く求めるためのものです。例えば、以下の$whereクエリーで、 db.things.find( "this.a % 10 == 1")
これは以下のように置き換えられます、 db.things.find( { a : { $mod : [ 10 , 1 ] } } )
$ne不等号には、$neを使ってください。 db.things.find( { x : { $ne : 3 } } );
$in$in オペレータは、SQLの IN に似ています。配列でマッチする組を指定できます。 db.collection.find( { "field" : { $in : array } } );
いくつかの例を見てみましょう。 things コレクションから、キー'j'の値によってサブセットを取得します。 db.things.find({j:{$in: [2,4,6]}});
updates コレクションはソーシャルネットワーク形式のニュースアイテムと仮定します。ここで、友人の最新の10個の最近のアップデートを取得したいとします。 db.updates.ensureIndex( { ts : 1 } ); // ts == timestamp
var myFriends = myUserObject.friends; // これは友人のデータベース参照を取得すると仮定しましょう。
var latestUpdatesForMe = db.updates.find( { user : { $in : myFriends } } ).sort( { ts : -1 } ).limit(10);
$nin$nin オペレータは、 $in に似ていますが、指定したフィールドに、指定した配列のどの値も含まれていないオブジェクトを選択します。たとえば、 db.things.find({j:{$nin: [2,4,6]}});
{j:1,b:2} にマッチしますが、 {j:2,c:9} にはしません。 $nor$nor オペレータでは、 boolean または式が扱えます。 $nor に式のリストを渡します。 $or$or オペレータを使うと、booleanまたは式をクエリで使うことができます。 $or に式のリストを渡します。
単純に、 db.foo.find( { $or : [ { a : 1 } , { b : 2 } ] } )
他のフィールドと db.foo.find( { name : "bob" , $or : [ { a : 1 } , { b : 2 } ] } )
$or 操作は、それぞれの条件にマッチするものを取得し、結果から重複したものを取り除きます。 $or での数々の最適化が 1.8 で予定されています。 このスレッド を参照。
$size$size オペレータは、指定された配列の要素のサイズにマッチします。次の例は、 {a:["foo"]} にマッチします。なぜならこの配列は1つの要素だからです。 db.things.find( { a : { $size: 1 } } );
$size で範囲指定をすることはできません(たとえば、 1つ以上の要素を持つ配列)。 範囲指定が必要な場合は、 size フィールドを自分で作り要素を加えるたびにインクリメントしてください。 $type$type オペレータは、値の BSON のタイプにマッチします. db.things.find( { a : { $type : 2 } } ); // stringにマッチ
db.things.find( { a : { $type : 16 } } ); // intにマッチ
指定できるタイプは:
BSONの一般的なタイプについては、 http://www.bsonspec.org を見てください。 正規表現データベースのクエリ表現で正規表現を使えます。 db.customers.find( { name : /acme.*corp/i } );
/^prefix/ のような、先頭一致をするだけの単純なクエリでは、データベースは可能であればインデックスを使います(多くのSQLデータベースが、 LIKE 'prefix%' に対してインデックスを使うのと似ています)。これは、 i (case-insensitivity) のオプションを付けてないときだけです。
MongoDB は PCRE を正規表現で使っています。 指定できるフラグは:
配列内の値colors フィールドの中の"red"を探すには、 db.things.find( { colors : "red" } );
"colors"が検索されるとき、もし配列だった場合、配列の各値が調べられます。 このテクニックは、 これと一緒に 以下の組み込みオブジェクトで一緒に使うことができます。 $elemMatchバージョン1.3.1以上が必要です。 $elemMatch は、配列の中の要素が指定した条件にマッチするかをチェックします。 > t.find( { x : { $elemMatch : { a : 1, b : { $gt : 1 } } } } )
{ "_id" : ObjectId("4b5783300334000000000aa9"),
"x" : [ { "a" : 1, "b" : 3 }, 7, { "b" : 99 }, { "a" : 11 } ]
}
一つの配列内の要素すべてが、指定した条件にマッチする必要があることに注意してください。 つまり、x配列内の異なった要素にマッチできる下記のクエリーは、意味的に違います。 > t.find( { "x.a" : 1, "x.b" : { $gt : 1 } } )
詳しくは、 ドット表記 参照 組み込みオブジェクト内の値例えば、 postings コレクション内の、組み込みのauthor オブジェクトから、 author.name=="joe" を探す場合、 db.postings.find( { "author.name" : "joe" } );
詳しくは、 ドット表記 参照 メタオペレータ: $not$not メタオペレータは、通常のオペレータを否定するときに使います。たとえば、 db.customers.find( { name : { $not : /acme.*corp/i } } );
db.things.find( { a : { $not : { $mod : [ 10 , 1 ] } } } );
Javascript 表現と $whereここまでで説明してきた構造化されたクエリーに加え、Javascriptの形式でクエリーを指定することもできます。これをするためには、Javascriptを含む文字列を find() に渡します。または、そのような文字列をオブジェクトのmemberである $where にアサインします。 データベースは、オブジェクトのスキャンにそのJavascriptを使い評価します。評価の結果が true の場合には、オブジェクトはクエリーの結果として返されます。 たとえば、次の各式は、すべての同じことをします。
db.myCollection.find({ a : { $gt: 3 } } );
db.myCollection.find( { $where: "this.a > 3" } );
db.myCollection.find("this.a > 3");
f = function() { return this.a > 3; } db.myCollection.find(f);
Javascriptの実行は、このページで紹介したネイティブのオペレーターよりも遅いですが、とても柔軟性があります。 詳しい情報は、 サーバ側でのコードの実行 を参照してください。 カーソルメソッドcount()count() メソッドは、指定したクエリにマッチするオブジェクトの数を返します。これは、MongoDBサーバ上で特別に最適化され実行されるので、クライアントサイドでするより速いし効率的です。 nstudents = db.students.find({'address.state' : 'CA'}).count();
以下の方法で同じ結果を取得することができますが、以下はすべてのドキュメントをクライアント側のメモリに入れてからカウントするので、遅いし非効率的です。しないでください。 nstudents = db.students.find({'address.state' : 'CA'}).toArray().length; // VERY BAD: 遅いし、多くのメモリを使います
skip()とlimit()を使うクエリでも、デフォルトではcountの結果はそれらを無視します。skipやlimitをした結果の値が必要な場合には、count(true)を使ってください。 n = db.students.find().skip(20).limit(10).count(true);
limit()limit() は、MySQLのLIMITに似ています。 これは、取得する最大の件数を指定します。 最高のパフォーマンスのためには、可能な限りいつでも limit() をつけてください。 そうしないと、データベースは、処理で必要な件数よりも多くの結果を返してしまうことがあります。 db.students.find().limit(10).forEach( function(student) { print(student.name + "<p>"); } );
skip()skip() で、返される結果がどのオブジェクトから始めるかを指定します。これは、 "ページング" を実装したいときに便利です。 以下は、JavaScriptアプリケーションでどう使われかの例です。 function printStudents(pageNumber, nPerPage) {
print("Page: " + pageNumber);
db.students.find().skip((pageNumber-1)*nPerPage).limit(nPerPage).forEach( function(student) { print(student.name + "<p>"); } );
}
snapshot()クエリーをsnapshotモードで使うことを明示します。snaphostモードは、クエリー実行中、最初から最後まで、(たとえオブジェクトが更新されても)重複した値や、存在しないオブジェクトを返さないことを保証します。もし、クエリー実行中に、オブジェクトが追加、削除された場合には、たとえばsnapshotモードでも、それらのオブジェクトは返されるかも(返されないかも)しれません。 短いクエリのレスポンス (1MB以下)では、常に事実上snapshotなことに注意してください。 現在のところ、 snapshotモードは、sortや明示的なhintを使った場合、使用されません。 sort()sort() はSQLでの、ORDER BYに似ています。これは、結果を特定の順序で返すことを要求します。 sort() に、希望する順を示すキーパターンを渡します。 db.myCollection.find().sort( { ts : -1 } ); // tsの降順でソートします
sort() は {[limit()}} と組み合わせて使えます。実際には、指定したキーパターンに関連するインデックスがない場合、 limit は、インデックスが使われないときソートされた件数を制限するので、推奨されます。 limit() またはインデックスなしでは、ソートがすべてインメモリで行われます。 limit() を使うことで、使用するメモリサイズを減らし、 最適化されたソートアルゴリズムを使うことによりスピードがあがります。 特別なオペレータdb.foo.find()._addSpecial("$returnKey" , true ) アイテムをスキャンする数を制限 db.foo.find()._addSpecial( "$maxScan" , 50 )
クエリーをセット db.foo.find()._addSpecial( "$query" : {x : {$lt : 5}} ) // これと同じ db.foo.find({x : {$lt : 5}}) 結果をソート db.foo.find()._addSpecial( "$orderby", {x : -1} ) // これと同じ db.foo.find().sort({x:-1}) 結果を返すのではなく、クエリの explain を返す db.foo.find()._addSpecial( "$explain", true ) // これと同じ db.foo.find().explain() スナップショットクエリ db.foo.find()._addSpecial( "$snapshot", true ) // これと同じ db.foo.find().snapshot() インデックスの範囲をセット ( minとmax クエリ指示子 参照) db.foo.find()._addSpecial("$min" , {x: -20})._addSpecial("$max" , { x : 200 }) 結果のディスク上の場所を表示 db.foo.find()._addSpecial("$showDiskLoc" , true) 指定したインデックスを強制 db.foo.find()._addSpecial("$hint", {_id : 1})
group()group() メソッドは、SQLの GROUP BY に似ていますが、 group() はもっと柔軟です。 任意のreductionのためのオペレーションを指定することができます。 詳しくは、 開発者ガイド の []集約 セクションを見てください。 その他
|

IF YOU HAVE A QUESTION, POST IT TO THE USER GROUP.
These pages are fine for comments, but for questions, your best bet will always be the MongoDB User Group. blog comments powered by Disqus