这是我的错误
E11000重复键错误集合:blog-api.blogs索引:id_1 dup 键:{id:空}
当我插入一个数据时,它正在插入,但之后我尝试插入数据,但出现上述错误。
以下是我的博客Schema.js
const mongoose = require("mongoose");
const blogSchema = mongoose.Schema(
{
title: { type: String, required: true },
author: { type: String, required: true },
body: { type: String, required: true },
comments: [{ body: String, date: Date }],
date: { type: Date, default: Date.now },
picturePath: {
type: String,
default: "",
},
meta: {
votes: Number,
favs: Number,
},
},
{ timestamps: true }
);
const Blog = mongoose.model("Blog", blogSchema);
module.exports = Blog;
这是我的添加博客功能
const addBlog = async (req, res) => {
try {
const { title, author, body } = req.body;
const picturePath = req.file.filename;
const result = await Blog.create({
title: title,
author: author,
body: body,
picturePath: picturePath,
});
res.status(200).send(result);
} catch (error) {
console.log(error);
res.status(500).send("Data format is not valid!");
}
};
如果有人知道导致上述错误的原因,请回答
以下帖子重现了该问题,讨论了一些观察结果,最后提供了针对此情况的解决方法或修复方案。请看看是否有用。
重现问题
请按照给定的顺序执行代码。
代码1
以下代码定义了一个包含密钥 ID 的架构,并将其定义为唯一。在此代码中还创建了一个新文档。然而,创建方法中省略了密钥 ID。
import mongoose, { Schema } from 'mongoose';
await main().catch((err) => {
console.log(err);
console.log(`Error thrown: ${new Date()}`);
});
mongoose.connection.on('error', (err) => {
console.log(err);
});
async function main() {
const uri = 'mongodb://127.0.0.1:27017/test';
//console.log(`Connecting: ${new Date()}`);
await mongoose.connect(uri);
const blogSchema = mongoose.Schema(
{
id: { type: String, unique: true },
title: { type: String, required: true },
author: { type: String, required: true },
body: { type: String, required: true },
comments: [{ body: String, date: Date }],
date: { type: Date, default: Date.now },
picturePath: {
type: String,
default: '',
},
meta: {
votes: Number,
favs: Number,
},
},
{ timestamps: true }
);
const Blog = mongoose.model('Blog', blogSchema);
const result = await Blog.create({
title: 'title',
author: 'author',
body: 'body',
picturePath: 'picturePath',
});
}
代码2
这是下一个要执行的代码。在此代码中,密钥 ID 已从架构定义中删除。在执行此代码时,它将抛出错误“E11000重复键错误集合:test.blogs索引:id_1 dup key:{id:null}”。但请注意,此代码的 create 方法中也省略了密钥 ID。
import mongoose, { Schema } from 'mongoose';
await main().catch((err) => {
console.log(err);
console.log(`Error thrown: ${new Date()}`);
});
mongoose.connection.on('error', (err) => {
console.log(err);
});
async function main() {
const uri = 'mongodb://127.0.0.1:27017/test';
//console.log(`Connecting: ${new Date()}`);
await mongoose.connect(uri);
const blogSchema = mongoose.Schema(
{
title: { type: String, required: true },
author: { type: String, required: true },
body: { type: String, required: true },
comments: [{ body: String, date: Date }],
date: { type: Date, default: Date.now },
picturePath: {
type: String,
default: '',
},
meta: {
votes: Number,
favs: Number,
},
},
{ timestamps: true }
);
const Blog = mongoose.model('Blog', blogSchema);
const result = await Blog.create({
title: 'title',
author: 'author',
body: 'body',
picturePath: 'picturePath',
});
}
观察结果:
在“代码1”中,密钥id已被定义并设置为唯一。运行“代码 1”时,它会自动在 MongoDB 数据库中创建唯一索引。这可以在 Mongo Shell 中验证,如下所示。
test> db.blogs.getIndexes();
[
{ v: 2, key: { _id: 1 }, name: '_id_' },
{
v: 2,
key: { id: 1 },
name: 'id_1',
background: true,
unique: true
}
]
在“代码 2”中,相同的密钥 ID 已从架构定义中删除。这次代码抛出了以下错误。
'E11000 duplicate key error collection: test.blogs index: id_1 dup key: { id: null }'
原因不言自明:
“代码 1”已经创建了一个具有空值的索引条目。
“代码 2”还尝试使用另一个空值创建索引条目,并导致错误。
请记住,在创建新文档时,“代码 1”和“代码 2”中的密钥 ID 已被省略。
观察总结:
每当 Mongoose 模式中的某个键被定义为唯一时,MongoDB 数据库中就会自动为该键创建一个唯一索引。
这个索引创建过程不依赖于新创建的文档中是否引用了索引键。
此外,如果新文档中省略了该键,则将自动提供空值并相应地创建索引条目。对于相同类型的文档也会重复相同的过程,这将导致在此上下文中出现错误。
解决方法/修复
解决方法或修复方法是手动删除索引,如下所示。请进入 Mongo shell 并通过连接到相应的数据库来执行以下命令。这将永久删除索引,并允许创建新文档而无需再查找该索引。
db.blogs.dropIndex({id:1});
谢谢
WoDoTheBest4You