MongoDB新增帖子触发E11000重复键错误(text:null)求助
解决MongoDB创建帖子时的E11000重复键错误
问题场景
实现MongoDB新增帖子功能,首次创建请求成功,但第二次创建时控制台抛出错误:
MongoServerError: E11000 duplicate key error collection: myFirstDatabase.posts index: text_1 dup key: { text: null }
相关代码片段
Mongoose Schema
const PostSchema = new mongoose.Schema({ title:{ type:String, require: true, unique: true, }, description: { type: String, require: true, unique: true, }, tags:{ type: Array, default:[], }, viewsCount: { type:Number, default: 0, }, user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', require:true, }, imageUrl:String, }, { timestamps: true, });
鉴权中间件
export default (req, res, next) => { const token = (req.headers.authorization || '').replace(/Bearer\s?/,''); if (token) { try { const decoded = jwt.verify(token, 'secret123'); req.userId = decoded._id; next(); } catch(e) { return res.status(403).json({ message:"нет доступа", }) } } else { return res.status(403).json({ message:"нет доступа", }) } }
创建帖子接口
export const createPost = async (req, res) => { try { const doc = new PostModel({ title: req.body.title, description: req.body.description, tags: req.body.tags, imageUrl: req.body.imageUrl, userId: req.userId, }); const post = await doc.save(); res.json(post); } catch(err) { console.log(err) res.status(500).json({ message: ' не удалось создать пост' }) } }
路由配置
app.post('/posts',checkAuth, postCreateValidation, createPost);
错误原因分析
错误中的text: null是因为你的posts集合中存在一个名为text_1的唯一索引,但当前Schema并未定义text字段。每次插入文档时,text字段默认值为null,而唯一索引不允许重复的null值,因此第二次插入触发了重复键错误。
可能的触发场景:
- 之前手动在集合中创建过
text字段的唯一索引,后续删除Schema中的text字段但未清理集合索引 - 第三方工具或脚本自动生成了该索引
解决步骤
确认集合中的索引
在MongoDB Shell中执行以下命令,查看posts集合的所有索引:use myFirstDatabase db.posts.getIndexes()删除多余的唯一索引
如果查询结果中存在text_1索引,执行命令删除:db.posts.dropIndex("text_1")修正Schema与代码的字段匹配问题
创建帖子时的字段名与Schema不匹配:代码中使用userId,但Schema定义的是user字段,会导致user字段缺失。修正接口代码:const doc = new PostModel({ title: req.body.title, description: req.body.description, tags: req.body.tags, imageUrl: req.body.imageUrl, user: req.userId, // 改为与Schema一致的字段名 });优化索引与字段约束(可选)
- 如果不需要标题和描述全局唯一,建议去掉
unique: true约束(普通场景下,不同用户发布相同标题/描述的帖子是合理需求) - 如果需要全文搜索功能,使用Mongoose的官方全文索引语法,而非手动创建单字段唯一索引:
// 在Schema定义后添加全文索引 PostSchema.index({ title: 'text', description: 'text' });
- 如果不需要标题和描述全局唯一,建议去掉
内容的提问来源于stack exchange,提问作者Максим Дмитриевич
相关产品推荐
相关产品推荐

