2013-05-30 7 views
25

Bu sorunla uğraştım.Mongoose - ölçütlere göre alt belgeleri bulma

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

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

Soru, nasıl her ebeveyn belgesinden (bu durumda, childrenSchema nesneler) tüm alt belgeleri getirmesi edilir: İki Gelincik şemaları var? - Tek bir sorguda - tüm çocukların mümkün mü 18 yaşından büyük

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 } 
    ]} 
]; 

ben almak istiyorum: Diyelim ki bazı veriler var varsayalım? Her cevap takdir edilecektir, teşekkürler!

+0

Eğer çocuk 18 yaşından büyük olduğunu ebeveyn dönmek sadece bunu istiyorum yoksa sadece çocukları doldurmak istiyorum yapıyorlar mı olduğunu her ebeveynin üzerinde 18 yaşın üstündedir? –

+0

"Çocuk" setini alırsam harika olur ... –

cevap

38

En son olan MongoDB sürümlerinde bir sorgu projeksiyon operatörü olarak $elemMatch kullanabilirsiniz. Bu children dizinin dışarı genç çocuk belgeleri filtreler

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

: Mongo kabuğundan Gördüğünüz gibi

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

, çocuklar hala ebeveynlerinin belgelerin içindeki gruplandırılır. MongoDB sorguları, belgeleri koleksiyonlardan döndürür.

> 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 
} 

Ben performans için $match maddesini tekrarlamak: Ayrı belgeler bölünmeleri toplama çerçevenin $unwind yöntemi kullanabilirsiniz içinden ilk kez hiçbir çocuklu en az 18 yaşında anne ortadan kaldırır, böylece $unwind sadece yararlı belgeleri dikkate alır. Ikinci $match, eşleşmeyen $unwind çıktısını kaldırır ve $project alt bilgileri en üst düzeye kadar çocuk bilgilerini kaldırır.

+0

Teşekkür ederim, kontrol edeceğim :) –

+0

Çalışıyor! :) Yardım için teşekkürler! :) Gelişmiş MongoDB operasyonları hakkında bazı dokümanları nereden alabilirim? Dokümanlar yeterli mi? MongoDB hakkında olabildiğince fazla bilgi edinmek istiyorum :) –

+1

10gen'in çevrimiçi MongoDB for Developers sınıfını al, Rick Copeland'ın MongoDB Tasarım Desenleri kitabını oku. –

16

Gelincik, ayrıca böyle zarif .populate() işlevini kullanabilirsiniz:

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

"populate", diğer koleksiyonlardaki belgelere başvururken çalışır . OP alt belgeleri kullanıyor. – Lulylulu

+0

Bu cevabı yaptığımdan bu yana çok uzun bir zaman geçti :) Şimdi deneyemiyorum, ama aynı zamanda gömülü dokümanlar için de çalışmalıyım! – AbdelHady