3

我有一个文章架构,用于用户在我的网站上发布的文章。它引用了用户集合:

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 hook 来填充参考:

ArticleSchema.post('find', function (doc) {
  doc.populate('author');
});

由于某种原因,挂钩中返回的文档没有填充方法。我是否必须使用 ArticleSchema 对象而不是在文档级别进行填充?

4

4 回答 4

4

上面的答案可能不起作用,因为它们通过不调用 next 来终止 pre hook 中间件。正确的实施应该是

productSchema.pre('find', function (next) {
this.populate('category','name');
this.populate('cableType','name');
this.populate('color','names');
next();

});

于 2019-02-07T16:54:34.597 回答
3

那是因为populate是查询对象的方法,而不是文档。您应该改用pre钩子,如下所示:

ArticleSchema.pre('find', function () {
    // `this` is an instance of mongoose.Query
    this.populate('author');
});
于 2016-05-31T04:44:22.493 回答
1

要补充的是,这里的文档将允许您继续使用下一个中间件。您还可以使用以下内容并仅选择一些特定字段。例如,用户模型有 name, email, address, and location,但您只想填充姓名和电子邮件

ArticleSchema.pre('find', function () {
    // `this` is an instance of mongoose.Query
    this.populate({path: 'author', select: '-location -address'});
});
于 2020-03-02T17:21:38.580 回答
0

来自MongooseJS 文档

查询中间件与文档中间件有一个微妙但重要的区别:在文档中间件中,这是指正在更新的文档。在查询中间件中,mongoose 不一定有对正在更新的文档的引用,因此它指的是查询对象而不是正在更新的文档。

我们无法从 post find 中间件内部修改结果,因为this引用了查询对象。

TestSchema.post('find', function(result) {
  for (let i = 0; i < result.length; i++) {
    // it will not take any effect
    delete result[i].raw;
  }
});
于 2017-02-21T22:34:28.827 回答