2014-06-25 27 views
11

alt alt:Gelincik doldurmak benim MongoDB</p> <p>Öğeler bu kurulum var belge

title: String 
comments: [] // of objectId's 

Yorumlar:

itemSchema = mongoose.Schema({ 
    title: String, 
    comments: [{ type: Schema.Types.ObjectId, ref: 'comments' }], 
}); 

Item = mongoose.model('items', itemSchema); 

commentSchema = mongoose.Schema({ 
    comment: String, 
    user: { type: Schema.Types.ObjectId, ref: 'users' }, 
}); 

Comment = mongoose.model('comments', commentSchema); 

:

user: ObjectId() 
item: ObjectId() 
comment: String 

İşte benim Gelincik şema var Eşyalarımı aldığım yer burası yorumlarla:

Item.find({}).populate('comments').exec(function(err, data){ 
    if (err) return handleError(err); 
    res.json(data); 
}); 

Yorumlar dizisini ilgili kullanıcıyla nasıl doldururum? Her yorumun bir kullanıcı ObjectId() olduğundan Sonuç nesneleri doldurmak çağıran bir tam örnek olarak

+0

Bu sorunun kabul edilen yanıtında gösterildiği gibi iki aşamada yapabilirsiniz: http://stackoverflow.com/questions/19222520/populate-nested-array-in-mongoose – JohnnyHK

cevap

22

:

Item.find({}).populate("comments").exec(function(err,data) { 
    if (err) return handleError(err); 

    async.forEach(data,function(item,callback) { 
     User.populate(item.comments,{ "path": "user" },function(err,output) { 
      if (err) throw err; // or do something 

      callback(); 
     }); 
    }, function(err) { 
     res.json(data); 
    }); 

}); 

ilk bağımsız değişken olduğu gibi modelinden çağrılan biçimde .populate() çağrısı, bir belge veya bir dizi değerleri alır. Bu nedenle, her bir öğe için döndürülen sonuçlara geçiş yaparsınız ve çağrı, her "yorum" dizisinde bu şekilde doldurulur. "Yol", işlevin eşleştiğini söyler.

Bu, forEach'ın "async" sürümü kullanılarak yapılır, bu nedenle engellenmez, ancak genellikle tüm manipülasyondan sonra yanıttaki tüm öğeler yalnızca yorumlarla doldurulur, ancak yorumların kendileriyle ilgili "kullanıcı" "ayrıntılar.

+0

Bu çok yardımcı oldu. Teşekkürler! – iamjonesy

+0

@neil Lunn Aşağıda hata alıyorum. Lütfen bana yardım edebilir misiniz? async.forEach (veri, işlev (madde, geri arama) { ^ ReferenceError: async tanımlı değil – FarheenP

+0

@FarheenP - 'npm install async' kullanarak yükleyin ve sonra bunu var varync = require ('async') Https://github.com/caolan/async – petrkotek

43

Bir daha yolu (kolay) bunun için:

Item 
 
    .find({}) 
 
    .populate({ 
 
\t path:  'comments', \t \t \t 
 
\t populate: { path: 'user', 
 
\t \t  model: 'users' } 
 
    }) 
 
    .exec(function(err, data){ 
 
    if (err) return handleError(err); 
 
    res.json(data); 
 
});

+0

Yanıtınız için teşekkürler Cevabınız harika – Bik

+0

müthiş, teşekkürler! – ksloan

+2

Bu arada, ilk nüfus için gerek yok – Bazinga

3

Item 
    .find({}) 
    .populate({ 
    path: 'comments.user', 
    model: 'users' } 
    }) 
    .exec(function(err, data){ 
    if (err) return handleError(err); 
    res.json(data); 
}); 
0

kişi özellikle tek seçmek için kullanmak isteyebilirsiniz son bir yöntemi eklemek için basit alt belgelerden alanlar, aşağıdaki 'select' sözdizimini kullanabilirsiniz:

Model.findOne({ _id: 'example' }) 
    .populate({ 
     path: "comments", // 1st level subdoc (get comments) 
     populate: { // 2nd level subdoc (get users in comments) 
     path: "user", 
     select: 'avatar name _id'// space separated (selected fields only) 
     } 
    }) 
    .exec((err, res) => { 
     // etc 
    });