在mongoose中填充嵌套数组 – Node.js

这些是我的模式(主题是父母,包含“思想”的列表):

var TopicSchema = new mongoose.Schema({ title: { type: String, unique: true }, category: String, thoughts: [ThoughtSchema] }, { timestamps: true, toObject: {virtuals: true}, toJSON: {virtuals: true} }); var ThoughtSchema = new mongoose.Schema({ text: String, author: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, votes:[{ _id:false, voter: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, up: Boolean, date: {type: Date, default: Date.now} }] }, { timestamps: true, toObject: {virtuals: true}, toJSON: {virtuals: true} }); .... 

我正在尝试阅读思想的作者,并改变我的get主题api像这样:

 ... var cursor = Topic.find(query).populate({ path: 'thoughts', populate: { path: 'author', model: 'User' } }).sort({popularity : -1, date: -1}); return cursor.exec() .then(respondWithResult(res)) .catch(handleError(res)); ... 

但作者是空的。我也没有在控制台中得到任何错误。 这里有什么问题?

编辑:其实我不需要作为一个模式思想,它没有自己的数据库中的集合。 它将被保存在主题中。 但为了使用时间戳选项的思想,我需要提取其内容到一个新的本地模式ThoughtSchema。 但是我现在直接在主题的想法数组中定义了thinkSchema的内容,但它仍然不起作用。

Edit2:这是执行之前的游标对象。 不幸的是我不能在Webstorm中debugging,这是来自节点检查器的截图:

在这里输入图像描述

怎么样

 Topic.find(query).populate('thoughts') .sort({popularity : -1, date: -1}) .exec(function(err, docs) { // Multiple population per level if(err) return callback(err); Topic.populate(docs, { path: 'thoughts.author', model: 'User' }, function(err, populatedDocs) { if(err) return callback(err); console.log(populatedDocs); }); }); 

你尝试使用Model.populate ?

 Topic.find(query).populate('thoughts') .sort({popularity : -1, date: -1}) .exec(function(err, docs) { // Multiple population per level if(err) return callback(err); Thought.populate(docs, { path: 'thoughts.author', model: 'User' }, function(err, populatedDocs) { if(err) return callback(err); console.log(populatedDocs); }); }); 

更新:
你可以尝试深入填充像这样:

 Topic.find(query).populate({ path: 'thoughts', populate: { path: 'author', model: 'User' } }) .sort({popularity : -1, date: -1}) .exec(function(err, docs) { if(err) return callback(err); console.log(docs); }); 

这些是模式:

 var TopicSchema = new mongoose.Schema({ title: { type: String, unique: true }, category: String, thoughts: [ThoughtSchema] }, { timestamps: true, toObject: {virtuals: true}, toJSON: {virtuals: true} }); var ThoughtSchema = new mongoose.Schema({ text: String, author: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, votes:[{ _id:false, voter: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, up: Boolean, date: {type: Date, default: Date.now} }] }, { timestamps: true, toObject: {virtuals: true}, toJSON: {virtuals: true} }); 

你尝试聚合,而不是填充。 聚合使用$lookup填充embedded的数据变得更容易。 尝试下面的代码。

UPDATE

 Topic.aggregate([{$unwind: "$thoughts"},{ $lookup: {from: 'users', localField: 'thoughts.author', foreignField: '_id', as: 'thoughts.author'}},{$sort:{{popularity : -1, date: -1}}}],function(err,topics){ console.log(topics) // `topics` is a cursor. // Perform Other operations here. }) 

说明

$ unwind :从input文档中解构一个数组字段,为每个元素输出一个文档。

$ lookup :$ lookup阶段在input文档的字段与“已join”集合的文档中的字段之间进行相等的匹配。 查找人口的工作。

$ lookup的作品就像

:这表示数据需要从哪个集合填充( users在这种情况下)。

localField :这是需要填充的本地字段。 (在这种情况下的ideas.author)。

foreignField :这是数据需要填充的集合中的外地字段(在这种情况下, users集合中的_id字段)。

因为 :这是您想要显示连接值的字段。 (这将投影ideas.author id作为思想。作者文件)。

希望这个作品。