使用预“查找”中间件填充多个字段
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();
);
【讨论】:
以上是关于使用预“查找”中间件填充多个字段的主要内容,如果未能解决你的问题,请参考以下文章