如何在创build后在mongoose中填充子文档?

我正在为item.comments列表添加评论。 在输出响应之前,我需要获取comment.created_by用户数据。 我应该怎么做?

Item.findById(req.param('itemid'), function(err, item){ var comment = item.comments.create({ body: req.body.body , created_by: logged_in_user }); item.comments.push(comment); item.save(function(err, item){ res.json({ status: 'success', message: "You have commented on this item", //how do i populate comment.created_by here??? comment: item.comments.id(comment._id) }); }); //end item.save }); //end item.find 

我需要在我的res.json输出中填充comment.created_by字段:

  comment: item.comments.id(comment._id) 

comment.created_by是我的mongoose CommentSchema中的用户参考。 它目前只给我一个用户ID,我需要填充所有的用户数据,除了密码和盐字段。

这是人们所问的模式:

 var CommentSchema = new Schema({ body : { type: String, required: true } , created_by : { type: Schema.ObjectId, ref: 'User', index: true } , created_at : { type: Date } , updated_at : { type: Date } }); var ItemSchema = new Schema({ name : { type: String, required: true, trim: true } , created_by : { type: Schema.ObjectId, ref: 'User', index: true } , comments : [CommentSchema] }); 

为了填充引用的子文档,您需要显式定义ID引用的文档集合(如created_by: { type: Schema.Types.ObjectId, ref: 'User' } )。

鉴于这个引用是定义好的,你的模式也可以很好地定义,现在你可以像平常一样调用populate (例如populate('comments.created_by')

概念validation码:

 // Schema var mongoose = require('mongoose'); var Schema = mongoose.Schema; var UserSchema = new Schema({ name: String }); var CommentSchema = new Schema({ text: String, created_by: { type: Schema.Types.ObjectId, ref: 'User' } }); var ItemSchema = new Schema({ comments: [CommentSchema] }); // Connect to DB and instantiate models var db = mongoose.connect('enter your database here'); var User = db.model('User', UserSchema); var Comment = db.model('Comment', CommentSchema); var Item = db.model('Item', ItemSchema); // Find and populate Item.find({}).populate('comments.created_by').exec(function(err, items) { console.log(items[0].comments[0].created_by.name); }); 

最后请注意, populate仅适用于查询,因此您需要先将您的项目传递给查询,然后调用它:

 item.save(function(err, item) { Item.findOne(item).populate('comments.created_by').exec(function (err, item) { res.json({ status: 'success', message: "You have commented on this item", comment: item.comments.id(comment._id) }); }); }); 

这可能已经改变,因为原来的答案是写,但它看起来像你现在可以使用模型填充function来做到这一点,而不必执行额外的findOne。 请参阅: http : //mongoosejs.com/docs/api.html#model_Model.populate 。 你想在保存处理程序中使用它,就像findOne一样。

@ user1417684和@ chris-foster是对的!

从工作代码摘录(没有error handling):

 var SubItemModel = mongoose.model('subitems', SubItemSchema); var ItemModel = mongoose.model('items', ItemSchema); var new_sub_item_model = new SubItemModel(new_sub_item_plain); new_sub_item_model.save(function (error, new_sub_item) { var new_item = new ItemModel(new_item); new_item.subitem = new_sub_item._id; new_item.save(function (error, new_item) { // so this is a valid way to populate via the Model // as documented in comments above (here @stack overflow): ItemModel.populate(new_item, { path: 'subitem', model: 'subitems' }, function(error, new_item) { callback(new_item.toObject()); }); // or populate directly on the result object new_item.populate('subitem', function(error, new_item) { callback(new_item.toObject()); }); }); }); 

我面临同样的问题,但经过几个小时的努力,我find了解决办法。它可以不使用任何外部插件:)

 applicantListToExport: function (query, callback) { this .find(query).select({'advtId': 0}) .populate({ path: 'influId', model: 'influencer', select: { '_id': 1,'user':1}, populate: { path: 'userid', model: 'User' } }) .populate('campaignId',{'campaignTitle':1}) .exec(callback); }