使用预“查找”中间件填充多个字段

Posted

技术标签:

【中文标题】使用预“查找”中间件填充多个字段【英文标题】:Populating multiple fields with a pre "find" middleware 【发布时间】:2022-01-15 21:15:17 【问题描述】:

我正在尝试在预“查找”中间件中指定应始终为用户文档填充的字段,如下所示:

userSchema.pre(/^find/, function (next) 
 this.populate("followers following"); next(); 
);

这是用户架构:

const userSchema = new mongoose.Schema<IUser>(
  
    firstName: 
      type: String,
      required: [true, "You must provide your first name."],
    ,
    lastName: 
      type: String,
      required: [true, "You must provide your last name."],
    ,
    profilePic: 
      type: String,
    ,
    email: 
      type: String,
      required: [true, "You must provide an email."],
      unique: true,
    ,
    password: 
      type: String,
      required: [true, "You must provide a password."],
    ,
    isVerified: 
      type: Boolean,
      default: false,
    ,
    verificationToken: 
      type: String,
    ,
    role: 
      type: String,
      enum: ["user", "admin"],
      default: "user",
    ,
    followers: [ type: mongoose.Schema.Types.ObjectId, ref: "User" ],
    following: [ type: mongoose.Schema.Types.ObjectId, ref: "User" ],
  ,
  
    timestamps: true,
  
);

但是当我发送请求时,它只是卡住了,没有发送任何响应。

当我只填充一个字段(“关注者”或“关注者”)时,它工作得很好,但在一起它就行不通了。 我尝试了很多不同的方法,但似乎没有任何效果。

如果有人能提供帮助,我将非常感激!

【问题讨论】:

【参考方案1】:

#1你试过把它们分开吗?

userSchema.pre('find', function (next)  
  this.populate("followers").populate("following");
  next();
);

#2 或者使用路径数组

userSchema.pre('find', function (next)  
  this.populate(['followers', 'following']);
  next();
);

如文档所述 here 和 here:

The Document#populate() method does not support chaining. You need to 
call populate() multiple times, or with an array of paths, to populate 
multiple paths.

#3 或者使用deep-populate,如果您按照here 记录的那样跨多个级别填充:

【讨论】:

我已经尝试链接填充方法(解决方案#1)并传入路径数组(解决方案#2),第三个解决方案对此没有帮助。很奇怪,这不适用于这些解决方案之一。 你能在问题中添加更多代码吗? 抱歉延迟响应...当我这样做时它完全正常:this.populate("followers") 或 this.populate("following"),这意味着这两种关系工作正常,所以我怀疑问题出在我的代码中的其他地方...... 试试this.populate( path: 'user', select: ['followers','following'] ) 我收到一个错误 - 无法填充路径“用户”,因为它不在您的架构中。我在 mongoose github repo 上发布了这个问题,但仍然没有人回答。好像做不到,但那太疯狂了……【参考方案2】:

我有有效的解决方案。

问题是如果中间件中的populate()方法有多个字段,它会为每个字段调用中间件并触发无限递归,导致请求挂起。

解决方法有点奇怪,但非常简单。我们必须添加_recursed 选项,以便中间件知道避免递归填充。

userSchema.pre(/^find/, function (next) 
   if (this.options._recursed) 
     return next();
   
   this.populate( path: "followers following", options:  _recursed: true  );
   next();
);

【讨论】:

以上是关于使用预“查找”中间件填充多个字段的主要内容,如果未能解决你的问题,请参考以下文章

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

如何使用链接从数据库中预填充表单字段?

如何使用jquery预填充字段

使用 Javascript 预填充日期输入字段

预填充的 html 字段中的引号

在猫鼬预中间件中,我如何访问更新查询?