这些是我的架构(主题是父级,包含一个'思想的列表):
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}
});
....
我正在尝试阅读这位思想的作者并改变我的获取主题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));
...
但是作者是null ..我也没有在控制台中得到任何错误。这有什么不对?
编辑:实际上我不需要思想作为架构,它在数据库中没有自己的集合。它将保存在主题中。但是为了在思想中使用 timestamps 选项,我需要将其内容提取到新的本地模式ThoughtSchema。但是我现在已经在思想主题数组中直接定义了thinkSchema的内容,它仍然不起作用。
Edit2:这是执行前的光标对象。不幸的是我无法在Webstorm中调试,这是节点检查员的截图:
答案 0 :(得分:0)
怎么样
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);
});
});
答案 1 :(得分:0)
您是否尝试使用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);
});
});
<强>更新强>
您可以尝试deep populate这样:
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);
});
答案 2 :(得分:0)
这些是模式:
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
更容易填充嵌入数据。请尝试以下代码。
<强>更新强>
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 :从输入文档中解构数组字段,为每个元素输出文档。
$ lookup :$ lookup阶段在输入文档中的字段与“已加入”集合的文档中的字段之间进行相等匹配。查找完成了人口的工作。
$ lookup的工作方式与
类似 来自的 :这表示需要从哪个集合中填充数据。(在此方案中为users
)。
localField :这是需要填充的本地字段。 (在此方案中为thoughts.author
)。
foreignField :这是需要填充数据的集合中的外部字段(在此方案中_id
集合中的users
字段)。
as :这是您要将联接值显示为的字段。 (这将投射ideas.author的id作为ideas.author文件)。
希望这有效。