Mongoose调用populate查询关联数组authSessions返回空值问题
Mongoose populate填充authSessions始终为空数组问题
问题表现
- 参照Mongoose官方文档实现关联对象populate逻辑,查询返回结果中
authSessions字段始终为空数组 - 已确认MongoDB中Session集合数据写入正常,每条Session记录的关联
userId字段值准确 - 尝试在populate中显式指定
path、model配置项后问题仍存在
相关代码与返回结果
Schema定义与查询代码
//Session.js const SessionSchema = new mongoose.Schema({ _id: Schema.Types.ObjectId, sessionId: { type: String, index: true }, createdDate: { type: Date, default: Date.now }, revoked: Boolean, revokedAt: Date, userId: {type: Schema.Types.ObjectId, ref: 'User', index: true} }) module.exports = mongoose.models.Session || mongoose.model('Session', SessionSchema); //User.js const UserSchema = new mongoose.Schema({ _id: Schema.Types.ObjectId, username: { type: String, index: true }, email: { type: String, index: true }, password: String, registrationDate: { type: Date, default: Date.now }, authSessions: [{type: Schema.Types.ObjectId, ref: 'Session'}] }) module.exports = mongoose.models.User || mongoose.model('User', UserSchema); // 查询逻辑 const user = await User.findById(session.userId).populate('authSessions').exec(); console.log(user) //authSessions始终为空
实际查询返回
{ _id: new ObjectId("62b6ea393e042868caa68c7d"), username: 'asdfasdfasdf', email: 'testaskldjflk@djlkajdf.com', password: 'testaskldjflk@djlkajdf.com', authSessions: [], // 该字段一直返回空数组 registrationDate: 2022-06-25T10:58:01.709Z, __v: 0 }
根因
Mongoose的常规populate逻辑不会自动做反向关联查询,它只会读取当前查询模型(此处为User)中待populate字段存储的_id列表,再去关联模型(此处为Session)中匹配对应文档返回。
你当前只在Session集合的每条记录里存了关联的userId,但User集合的对应文档中,authSessions数组本身就没有写入任何Session记录的_id,自然populate不出任何数据。
修复方案
可二选一:
- 方案1:保留现有Schema定义,创建Session时同步维护双向关联
每次新建Session记录时,把新生成的Session_id追加到对应用户的authSessions数组中:
完成这步后再用原有populate逻辑查询,就能正常拿到关联的Session列表。// 创建Session示例 const newSession = await Session.create({ _id: new mongoose.Types.ObjectId(), sessionId: "实际生成的sessionId", userId: targetUserId, // 其余字段按需传入 }) // 同步更新关联用户的authSessions字段 await User.findByIdAndUpdate(targetUserId, { $push: { authSessions: newSession._id } }) - 方案2:改用虚拟属性populate(虚拟填充),无需修改现有存量数据,也不用维护User侧的外键
修改User模型的Schema定义,新增虚拟关联字段:
改完后原有populate逻辑不需要调整,Mongoose会自动用当前User的// User.js 中补充虚拟字段配置 UserSchema.virtual("authSessions", { ref: "Session", localField: "_id", foreignField: "userId", justOne: false // 返回数组格式的多条匹配结果 }) // 开启虚拟字段序列化输出,否则查询结果看不到该字段 UserSchema.set("toObject", { virtuals: true }); UserSchema.set("toJSON", { virtuals: true });_id去Session集合匹配userId相等的记录填充到authSessions字段,不需要额外做双向数据同步。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

