E11000重复键错误集合:blog-api.blogs索引:id_1 dup key:{id:null}

问题描述 投票:0回答:1

这是我的错误

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!");
  }
};

如果有人知道导致上述错误的原因,请回答

javascript node.js mongodb
1个回答
0
投票

以下帖子重现了该问题,讨论了一些观察结果,最后提供了针对此情况的解决方法或修复方案。请看看是否有用。

重现问题

请按照给定的顺序执行代码。

代码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

© www.soinside.com 2019 - 2024. All rights reserved.