在后钩中间填充猫鼬中的“查找”

Posted

技术标签:

【中文标题】在后钩中间填充猫鼬中的“查找”【英文标题】:populate in post hook middlewhere for 'find' in mongoose 【发布时间】:2015-09-08 07:46:23 【问题描述】:

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

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 对象而不是在文档级别进行填充?

【问题讨论】:

编辑:我们已经离开了 mongo 来做这样的事情。对于大多数生产应用程序来说,使用关系数据库要容易得多。我们使用 postgresql。 【参考方案1】:

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

ArticleSchema.pre('find', function () 
    // `this` is an instance of mongoose.Query
    this.populate('author');
);

【讨论】:

【参考方案2】:

来自MongooseJS Doc:

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

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

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

【讨论】:

【参考方案3】:

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

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

);

【讨论】:

【参考方案4】:

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

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

【讨论】:

以上是关于在后钩中间填充猫鼬中的“查找”的主要内容,如果未能解决你的问题,请参考以下文章

如何通过填充字段在猫鼬中查找文档?

通过在猫鼬中填充匹配结果来查找文档

如何通过猫鼬中的嵌套属性查找

通过猫鼬中的两个值查找数据

在猫鼬中,如何根据相关集合中的值查找记录?

在猫鼬中查找 ID 数组