You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取MongoDB中指定任务关联的用户(Mongoose实现)

问题描述

我正在开发一个Web应用,使用MongoDB与Mongoose,此前因上手便捷选择该数据库,但当前部分场景似乎更适合关系型数据库。不过我希望先尝试用MongoDB解决问题,再考虑重构数据库代码。

我有三个集合:用户、待办任务(pending jobs)、已完成任务(completed jobs)。待办任务执行后需从集合删除,并创建已完成任务条目。用户模型通过Object ID引用列表字段关联这两个任务集合,我已掌握如何通过用户获取其所有待办和已完成任务:

const resp = await User.findOne({username:username}).populate(['pendingJobs', 'completedJobs'])

但我不清楚如何获取指定任务所属的用户?

补充模型代码

待办任务模型

const pendingJobModel = new mongoose.Schema({
    date:{type:String, required: true, unique:true},
    startTime:{type:String, required: true},
    endTime:{type:String, required: true},
    courseList:{type:[String], required: true},
    member:{type:String},
    clubUsername:{type:String, required: true},
    clubPassword:{type:{token:String, iv:String}, required:true},
    proxy:{type:Boolean, required: true, default:false},
    active:{type:Boolean, required: true, default:false},
},{collection:'pendingjobs'})

module.exports = mongoose.model('PendingJob', pendingJobModel)

已完成任务模型

const completedJobModel = new mongoose.Schema({
    date:{type:String, required: true, unique:true},
    successful:{type:String, required: true},
    time:{type:String},
    course:{type:String},
    member:{type:String},
},{collection:'completedjobs'})

module.exports = mongoose.model('CompletedJob', completedJobModel)

用户模型

const userModel = new mongoose.Schema({
    username:{type:String, required: true, unique:true},
    password:{type:String, required: true,},
    refreshToken:{type:String, default: ''},
    proxyConfig:{type: mongoose.Types.ObjectId, ref:'Proxy'},
    pendingJobs:{type: [mongoose.Types.ObjectId], ref:'PendingJob'},
    completedJobs:{type: [mongoose.Types.ObjectId], ref:'CompletedJob'}
},{collection:'users'})

module.exports = mongoose.model('User', userModel)
解决方案

方法1:不修改现有模型,反向查询用户集合

当前只有用户集合存储了任务的引用,所以可以通过$in操作符在用户集合中查找包含指定任务ID的文档:

查询待办任务所属用户

// 假设已获取待办任务ID:pendingJobId
const user = await User.findOne({ pendingJobs: pendingJobId });

查询已完成任务所属用户

// 假设已获取已完成任务ID:completedJobId
const user = await User.findOne({ completedJobs: completedJobId });

注意:这种方式的缺点是用户集合数据量大时,查询效率会偏低,因为MongoDB需要遍历每个用户文档检查数组是否包含目标ID。

方法2:修改模型添加反向引用(推荐)

为了提升查询效率,建议在任务模型中添加指向用户的引用字段,直接通过任务文档关联用户:

修改待办任务模型

const pendingJobModel = new mongoose.Schema({
    // 原有字段保留
    date:{type:String, required: true, unique:true},
    startTime:{type:String, required: true},
    endTime:{type:String, required: true},
    courseList:{type:[String], required: true},
    member:{type:String},
    clubUsername:{type:String, required: true},
    clubPassword:{type:{token:String, iv:String}, required:true},
    proxy:{type:Boolean, required: true, default:false},
    active:{type:Boolean, required: true, default:false},
    // 添加用户引用字段
    user: { type: mongoose.Types.ObjectId, ref: 'User', required: true }
},{collection:'pendingjobs'})

module.exports = mongoose.model('PendingJob', pendingJobModel)

修改已完成任务模型

const completedJobModel = new mongoose.Schema({
    // 原有字段保留
    date:{type:String, required: true, unique:true},
    successful:{type:String, required: true},
    time:{type:String},
    course:{type:String},
    member:{type:String},
    // 添加用户引用字段
    user: { type: mongoose.Types.ObjectId, ref: 'User', required: true }
},{collection:'completedjobs'})

module.exports = mongoose.model('CompletedJob', completedJobModel)

同步更新逻辑

  • 创建待办任务时,需同时将任务ID添加到用户的pendingJobs数组,并在任务文档中存储用户ID;
  • 待办任务完成后,删除用户pendingJobs中的该任务ID,添加到completedJobs数组,同时创建已完成任务时存储用户ID。

查询任务所属用户

现在可以直接通过populate关联用户:

查询待办任务所属用户

const pendingJob = await PendingJob.findById(pendingJobId).populate('user');
// pendingJob.user 即为所属用户

查询已完成任务所属用户

const completedJob = await CompletedJob.findById(completedJobId).populate('user');
// completedJob.user 即为所属用户

这种方式能利用MongoDB索引优化查询,数据量较大时效率更优。

内容的提问来源于stack exchange,提问作者Carter James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 03:50:26