写点什么

mongodb 出现重复 id 怎么办?

作者:喵叔
  • 2021 年 12 月 03 日
  • 本文字数:894 字

    阅读完需:约 3 分钟

这个问题是我带的徒弟今天遇到的,程序在向 mongodb 中插入数据时出现 id 重复的错误,出错的提示如下:


duplicate key error collection: index: id dup key: { : ObjectId(‘68a3c9271f063c20cf82dec9’) }’,
复制代码


看到这个错误提示你一定会很奇怪 id 不是自己生成的,怎么会重复呢?要解答这个问题,我们先来看一下 ObjectId 以及什么是 id。id 是集合中文档的主键,用于区分文档,它自动编入索引,并且指定 {id:} 查找是以 id 索引作为指南的。默认情况下 id 字段的类型为 ObjectId,它是 MongoDB 的 BSON 类型之一。如果用户需要还可以将 id 设置为为 ObjectId 以外的其他类型。ObjectId 长度为 12 个字节,由几个 2 到 4 字节的链组成。每一个链代表并指定文档身份的具体内容。下面就列出了完整的 12 个字节组合:


  1. 4 字节的值表示自 Unix 纪元以来的秒数;

  2. 3 字节的机器标识符;

  3. 2 字节的进程 id;

  4. 3 字节的计数器,它以随机值开始。


一般来说,如果文档尚未分配 id 值,则 MongoDB 将会自动生成一个 id 值。我们先来尝试解决一下这个问题,首先我想到的解决方案是这样的:


  1. 首先我们的代码时批量插入的


Collectwrite.InsertMany(item);
复制代码


  1. 我们把它改成循环,每次只添加一个


foreach(var item in list){  Collectwrite.InsertOne(item);}
复制代码


但是运行代码还是报错,那么我们在每次田间后都暂停 500 毫秒呢?


Collectwrite.InsertOne(item);Thread.Sleep(500);
复制代码


再次运行代码,还是同样的错误。那么这是怎么回事呢?很多情况下 id 是根据时间戳+主机+进程号+序列生成的,那么重复的原因可能有以下两种:


  1. 同一时间插入了两条数据,导致了数据库生成了同一个 id 值;

  2. 每次使用同一个变量存储不同的数据,进而导致 mangodb 认为每次存储的是同一条数据,最终生成同一个 id 值。


这两种原因都有个共同点,那就是让 mongodb 自己生成 id。那么我们可以不让 mongodb 自己生成 id,我们自己手动添加 id,当插入的数据带有 id 的字段时,mongodb 就不再自动生成 id。至此, mongodb 重复 id 的问题就解决了。解决代码如下:


Collectwrite.DeleteMany(x => x.SeasonId == seasonId);foreach(var item in list){  item.Id = ObjectId.GenerateNewId().ToString();  Collectwrite.InsertOne(item);  Thread.Sleep(500);}
复制代码


用户头像

喵叔

关注

还未添加个人签名 2020.01.14 加入

还未添加个人简介

评论

发布
暂无评论
mongodb出现重复id怎么办?