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

如何在Mongoose中更新用户角色数组并避免重复值

给用户批量添加角色时避免重复条目

问题场景

现有两个MongoDB集合:

  • Roles:存储角色信息
  • Users:存储用户信息,其中roles字段是引用Roles集合的ObjectId数组

当前代码使用$push批量给用户添加角色时,会出现重复添加同一角色的问题(比如同一个管理员角色被多次加入用户的roles数组),相关代码及问题截图如下:

User Schema

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
    id: { type: String }, 
    username: { type: String, required: true, unique: true },
    phone: { type: String, required: false, unique:true }, 
    email: { type: String, required: true, unique: true },
    password: { type: String, required: true },
    roles: [
        { type: mongoose.Schema.Types.ObjectId, required: true, ref:'Role' } 
    ],
    otp: {
        required: false,
        type:String
    }
});

module.exports = mongoose.model('User', userSchema);

原问题代码

const rolesArr = get(validated, 'value.roles'); // ['super-administrator', 'administrator']
const usernameArr = get(validated, 'value.users'); // ['user-1', 'user-2']

const roles = await Role.find({slug:{$in:rolesArr}}); // 匹配角色slug的Roles集合数组

const set = {      
    $push: {         // 向现有数组中推送元素
        roles: roles
    }
}

const users = await User.updateMany({username: {$in: usernameArr}}, set);

问题截图

重复角色条目截图

解决方案

核心是使用MongoDB的$addToSet操作符替代$push,$addToSet会自动忽略数组中已存在的元素;配合$each可以实现批量添加多个元素。

修改后的代码

const rolesArr = get(validated, 'value.roles'); // ['super-administrator', 'administrator']
const usernameArr = get(validated, 'value.users'); // ['user-1', 'user-2']

// 查询目标角色并提取ObjectId数组
const roles = await Role.find({ slug: { $in: rolesArr } });
const roleIds = roles.map(role => role._id);

// 使用$addToSet + $each实现去重批量添加
const updateOptions = {      
    $addToSet: {
        roles: { $each: roleIds }
    }
}

const users = await User.updateMany({ username: { $in: usernameArr } }, updateOptions);

代码说明

  1. 提取角色ID:将查询到的Role对象转换为ObjectId数组,确保存入users.roles的是正确的引用类型
  2. $addToSet + $each:
    • $addToSet:仅当元素不存在于数组中时才添加
    • $each:允许批量传入多个元素,否则$addToSet会把整个数组当成单个元素插入

这样就能保证每个用户的roles数组中不会出现重复的角色条目。

内容的提问来源于stack exchange,提问作者Alaksandar Jesus Gene

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:26:12