Node.js 在mongoose中“查找”的位置填充

Node.js 在mongoose中“查找”的位置填充,node.js,mongodb,mongoose,middleware,mongoose-populate,Node.js,Mongodb,Mongoose,Middleware,Mongoose Populate,我有一个用户在我的网站上发布文章的文章模式。它引用用户集合: 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: 'Use

我有一个用户在我的网站上发布文章的文章模式。它引用用户集合:

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');
});
出于某种原因,钩子中返回的文档没有populate方法。我是否必须使用ArticleSchema对象而不是在文档级别进行填充?

这是因为填充是查询对象的一种方法,而不是文档。您应该使用预挂钩,如下所示:

ArticleSchema.pre('find', function () {
    // `this` is an instance of mongoose.Query
    this.populate('author');
});
发件人:

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

我们不能从post find中间件内部修改结果,因为它引用了查询对象

TestSchema.post('find', function(result) {
  for (let i = 0; i < result.length; i++) {
    // it will not take any effect
    delete result[i].raw;
  }
});

上述答案可能不起作用,因为它们通过不调用next来终止预挂接中间件。正确的执行应该是

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

要添加,此处的文档将允许您继续下一个中间件。 您还可以使用以下选项,并仅选择一些特定字段。例如,用户模型具有名称、电子邮件、地址和位置,但您只希望填充名称和电子邮件

ArticleSchema.pre('find', function () {
    // `this` is an instance of mongoose.Query
    this.populate({path: 'author', select: '-location -address'});
});

编辑:我们已经从mongo搬到了这里。对于大多数生产应用程序,使用关系数据库要容易得多。我们使用postgresql。