填充在post hook中间位置,用于在猫鼬中找到'find'

时间:2015-06-22 18:18:47

标签: node.js mongodb mongoose middleware mongoose-populate

我有一个文章架构,供用户在我的网站上发布的文章。它引用了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对象而不是文档级别填充?

4 个答案:

答案 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)

来自MongooseJS Doc

  

查询中间件与文档中间件的区别在于一种微妙但重要的方式:在文档中间件中,这指的是正在更新的文档。在查询中间件中,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();

});