在mongoose中为“find”操作编写后置钩子中间件的填充方法

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调用中都能使用后置钩子来填充引用:
ArticleSchema.post('find', function (doc) {
  doc.populate('author');
});

由于某些原因,在钩子中返回的文档没有populate方法。我是否需要使用ArticleSchema对象而不是在文档级别上进行填充?


1
编辑:对于此类问题,我们已经放弃了使用Mongo。大多数生产应用程序使用关系型数据库更容易。我们使用PostgreSQL。 - PGT
4个回答

4
以上答案可能无法起作用,因为它们通过未调用next终止了pre hook中间件。正确的实现应该是:
productSchema.pre('find', function (next) {
this.populate('category','name');
this.populate('cableType','name');
this.populate('color','names');
next();

});


3
那是因为populate是查询对象的一个方法,而不是文档的方法。你应该使用一个pre钩子,像这样:
ArticleSchema.pre('find', function () {
    // `this` is an instance of mongoose.Query
    this.populate('author');
});

1
添加到这里,doc将允许您继续到下一个中间件。您还可以使用以下内容仅选择一些特定字段。例如,用户模型具有姓名,电子邮件,地址和位置,但您只想填充姓名和电子邮件。
ArticleSchema.pre('find', function () {
    // `this` is an instance of mongoose.Query
    this.populate({path: 'author', select: '-location -address'});
});

0

来自 MongooseJS 文档

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

我们无法在 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;
  }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接