我有一个文章架构,供用户在我的网站上发布的文章。它引用了Users集合:
var ArticleSchema = new Schema({
title: { // NO MARKDOWN FOR THIS, just straight up text for separating from content
type: String,
required: true
},
author: {
type: Schema.Types.ObjectId,
ref: 'User'
}
});
我希望在所有find / findOne调用上都有一个post挂钩来填充引用:
ArticleSchema.post('find', function (doc) {
doc.populate('author');
});
由于某种原因,在钩子中返回的doc没有populate方法。我是否必须使用ArticleSchema对象而不是文档级别填充?
答案 0 :(得分:2)
那是因为populate
是查询对象的方法,而不是文档。您应该使用pre
挂钩,如下所示:
ArticleSchema.pre('find', function () {
// `this` is an instance of mongoose.Query
this.populate('author');
});
答案 1 :(得分:1)
要添加,这里的 doc 将允许您继续使用下一个中间件。
您还可以使用以下内容并仅选择一些特殊字段。例如,用户模型具有name, email, address, and location
,但是您只想填充名称和电子邮件地址
ArticleSchema.pre('find', function () {
// `this` is an instance of mongoose.Query
this.populate({path: 'auth', select: '-location -address'});
});
答案 2 :(得分:0)
查询中间件与文档中间件的区别在于一种微妙但重要的方式:在文档中间件中,这指的是正在更新的文档。在查询中间件中,mongoose不一定具有对正在更新的文档的引用,因此这指的是查询对象而不是正在更新的文档。
我们无法修改帖子查找中间件中的结果,因为此指的是查询对象。
TestSchema.post('find', function(result) {
for (let i = 0; i < result.length; i++) {
// it will not take any effect
delete result[i].raw;
}
});
答案 3 :(得分:0)
以上答案可能不起作用,因为它们通过不调用next来终止pre hook中间件。正确的实现应为
productSchema.pre('find', function (next) {
this.populate('category','name');
this.populate('cableType','name');
this.populate('color','names');
next();
});