node.js 创建后如何在 mongoose 中填充子文档?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13026486/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to populate a sub-document in mongoose after creating it?
提问by chovy
I am adding a comment to an item.comments list. I need to get the comment.created_by user data before I output it in the response. How should I do this?
我正在向 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
I need to populate the comment.created_by field here in my res.json output:
我需要在 res.json 输出中填充 comment.created_by 字段:
comment: item.comments.id(comment._id)
comment.created_by is a user reference in my mongoose CommentSchema. It currently is only giving me a user id, I need it populated with all the user data, except for password and salt fields.
comment.created_by 是我的猫鼬 CommentSchema 中的用户引用。它目前只给我一个用户 ID,我需要用所有用户数据填充它,密码和盐字段除外。
Here is the schema as people have asked:
这是人们询问的架构:
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]
});
回答by jsalonen
In order to populate referenced subdocuments, you need to explicitly define the document collection to which the ID references to (like created_by: { type: Schema.Types.ObjectId, ref: 'User' }).
为了填充引用的子文档,您需要明确定义 ID 引用的文档集合(如created_by: { type: Schema.Types.ObjectId, ref: 'User' })。
Given this reference is defined and your schema is otherwise well defined as well, you can now just call populateas usual (e.g. populate('comments.created_by'))
鉴于此引用已定义并且您的架构也已定义良好,您现在可以populate像往常一样调用(例如populate('comments.created_by'))
Proof of concept code:
概念验证代码:
// 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);
});
Finally note that populateworks only for queries so you need to first pass your item into a query and then call it:
最后请注意,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)
});
});
});
回答by user1417684
This might have changed since the original answer was written, but it looks like you can now use the Models populate function to do this without having to execute an extra findOne. See: http://mongoosejs.com/docs/api.html#model_Model.populate. You'd want to use this inside the save handler just like the findOne is.
自原始答案编写以来,这可能已经改变,但看起来您现在可以使用模型填充函数来执行此操作,而无需执行额外的 findOne。请参阅:http: //mongoosejs.com/docs/api.html#model_Model.populate。您可能想在保存处理程序中使用它,就像 findOne 一样。
回答by chhtm
@user1417684 and @chris-foster are right!
@user1417684 和 @chris-foster 是对的!
excerpt from working code (without 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());
});
});
});
回答by S Kumar
I faced the same problem,but after hours of efforts i find the solution.It can be without using any external plugin:)
我遇到了同样的问题,但经过数小时的努力,我找到了解决方案。它可以不使用任何外部插件:)
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);
}

