在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作为思想。作者文件)。
希望这个作品。