2013-05-30 12 views
25

私はちょうどこの問題に固執しています。マングース - 基準によるサブ文書の検索

var childrenSchema = mongoose.Schema({ 
    name: { 
     type: String 
    }, 
    age: { 
     type: Number, 
     min: 0 
    } 
}); 

var parentSchema = mongoose.Schema({ 
    name : { 
     type: String 
    }, 
    children: [childrenSchema] 
}); 

質問は、どのようにすべての親ドキュメントから(この場合は、childrenSchemaオブジェクト)のすべてのサブ文書を取得することです:私は2つのマングースのスキーマを持っていますか?のは、私はいくつかのデータを持っているとしましょう:

var parents = [ 
    { name: "John Smith", 
    children: [ 
     { name: "Peter", age: 2 }, { name: "Margaret", age: 20 } 
    ]}, 
    { name: "Another Smith", 
    children: [ 
     { name: "Martha", age: 10 }, { name: "John", age: 22 } 
    ]} 
]; 

私が取得したい - 単一のクエリで - 18はそれが可能であるよりも、すべての子どもたちが古いですか?すべての答えは、感謝されます、ありがとう!

+0

あなただけにそれをしたいか、子供が18歳以上であるか、あなたはそれだけでその子供を移入したくない場合は、親を返しますそれぞれの親は18歳以上ですか? –

+0

「子供たち」のセットを手に入れれば素晴らしいかもしれません... –

答えて

38

最新のMongoDBバージョンでは、$elemMatchをクエリ投影演算子として使用できます。これはchildren配列のうち、年少の子供たちのドキュメントをフィルタリング

db.parents.find(
    {'children.age': {$gte: 18}}, 
    {children:{$elemMatch:{age: {$gte: 18}}}}) 

:モンゴシェルからあなたが見ることができるように

{ "_id" : ..., "children" : [ { "name" : "Margaret", "age" : 20 } ] } 
{ "_id" : ..., "children" : [ { "name" : "John", "age" : 22 } ] } 

、子供たちはまだ彼らの親ドキュメント内でグループ化されています。 MongoDBは、コレクションから文書を返すことを問い合わせます。私は、パフォーマンスのために$match句繰り返し

> db.parents.aggregate({ 
    $match: {'children.age': {$gte: 18}} 
}, { 
    $unwind: '$children' 
}, { 
    $match: {'children.age': {$gte: 18}} 
}, { 
    $project: { 
     name: '$children.name', 
     age:'$children.age' 
    } 
}) 
{ 
    "result" : [ 
     { 
      "_id" : ObjectId("51a7bf04dacca8ba98434eb5"), 
      "name" : "Margaret", 
      "age" : 20 
     }, 
     { 
      "_id" : ObjectId("51a7bf04dacca8ba98434eb6"), 
      "name" : "John", 
      "age" : 22 
     } 
    ], 
    "ok" : 1 
} 

:あなたは別の文書にそれらを分割する集約フレームワークの$unwindメソッドを使用することができ、それは、少なくとも18歳なし子供と両親をなくして初めてなので、 $unwindは有用な文書のみを考慮します。 2番目の$matchは、一致しない$unwind出力を削除し、$projectは、サブ文書の最上位レベルの子情報を持ち上げます。マングースで

+0

ありがとう、私はそれをチェックします:) –

+0

それは動作します! :) 手伝ってくれてありがとう! :)高度なMongoDB操作については、どこから入手できますか?そのドキュメントで十分ですか?私はMongoDBについてできるだけ勉強したいと思っています:) –

+1

10genのオンラインMongoDB for Developersクラスで、Rick CopelandのMongoDB Design Patternsの本を読んでください。 –

16

、あなたはまた、次のようにエレガントな.populate()機能を使用することができます。

parents 
.find({}) 
.populate({ 
    path: 'children', 
    match: { age: { $gte: 18 }}, 
    select: 'name age -_id' 
}) 
.exec() 
+1

'populate'は他のコレクションのドキュメントを参照するときに機能します。 OPはサブ文書を使用しています。 – Lulylulu

+0

私はこの答えを作って以来、長い時間です:)&私は今それを試すことはできませんが、私はそれも組み込みドキュメントのために動作するはずだと思います! – AbdelHady