Mongo更新文档时触发E11000重复键错误,求排查方案
解决MongoDB E11000重复键错误(voters字段)
错误原因
你遇到的E11000 duplicate key error,是因为MongoDB的elections集合中,voters字段被创建了唯一索引(索引名voters_1)。你的代码逻辑是用$push往voters数组里添加已投票用户名,当同一个用户再次投票时,就会触发唯一索引的重复校验,抛出错误。
注意:你的Mongoose Schema里并没有给voters定义唯一约束,这个索引应该是之前手动在MongoDB中创建,或其他操作误添加的。
解决方案
步骤1:删除多余的唯一索引
连接MongoDB,执行以下命令删除voters字段的唯一索引:
db.elections.dropIndex("voters_1")
步骤2:添加投票重复校验逻辑
在修改文档前,先检查用户是否已投票,避免重复操作;同时用原子操作优化投票计数逻辑,避免竞态条件。
修改后的后端代码
import connectDb from "@/middleware/db"; import Election from "@/models/Election"; const jwt = require("jsonwebtoken"); const Vote = async (req, res) => { try { await connectDb(); // 验证JWT token const u = jwt.verify(req.body.token, "!stackoverflow!"); const username = u.username; const electionSlug = req.body.slug; const candidateIndex = req.body.i; // 检查用户是否未投票,同时获取选举数据 const election = await Election.findOne({ election_name: electionSlug, voters: { $ne: username } }); if (!election) { return res.json({ success: false, message: "用户已投票或选举不存在" }); } // 原子更新:自增候选人票数 + 添加投票用户 const updatedElection = await Election.findOneAndUpdate( { election_name: electionSlug }, { $push: { voters: username }, $inc: { [`votes.${candidateIndex}`]: 1 } }, { new: true } ); res.json({ success: !!updatedElection }); } catch (error) { console.error("Error in Vote:", error); res.status(500).json({ success: false, error: error.message }); } }; export default Vote;
内容的提问来源于stack exchange,提问作者Vraj
相关产品推荐
相关产品推荐

