Mongodb mongoose中的E11000重复键错误索引

时间:2014-06-26 12:12:31

标签: node.js mongodb mongoose

以下是user模型中的user.js架构 -

var userSchema = new mongoose.Schema({
    local: {
        name: { type: String },
        email : { type: String, require: true, unique: true },
        password: { type: String, require:true },
    },
    facebook: {
        id           : { type: String },
        token        : { type: String },
        email        : { type: String },
        name         : { type: String }
    }
});

var User = mongoose.model('User',userSchema);

module.exports = User;

这就是我在控制器中使用它的方法 -

var user = require('./../models/user.js');

这就是我在db -

中保存它的方法
user({'local.email' : req.body.email, 'local.password' : req.body.password}).save(function(err, result){
    if(err)
        res.send(err);
    else {
        console.log(result);
        req.session.user = result;
        res.send({"code":200,"message":"Record inserted successfully"});
    }
});

错误 -

{"name":"MongoError","code":11000,"err":"insertDocument :: caused by :: 11000 E11000 duplicate key error index: mydb.users.$email_1  dup key: { : null }"} 

我检查了db集合,没有这样的重复条目,让我知道我做错了什么?

仅供参考 - req.body.emailreq.body.password正在获取值。

我也检查过这篇文章,但没有帮助STACK LINK

如果我完全删除它然后插入文档,否则它会抛出错误“重复”错误,即使我在local.email中有一个条目

31 个答案:

答案 0 :(得分:179)

错误消息表示已存在null作为电子邮件的记录。换句话说,您已经拥有一个没有电子邮件地址的用户。

相关文件:

  

如果文档没有唯一索引中索引字段的值,则索引将为此文档存储空值。由于唯一约束,MongoDB只允许一个缺少索引字段的文档。如果有多个文档没有索引字段的值或缺少索引字段,则索引构建将失败并出现重复键错误。

     

您可以将唯一约束与稀疏索引结合使用,以从唯一索引中过滤这些空值,并避免错误。

unique indexes

  

稀疏索引仅包含具有索引字段的文档的条目,即使索引字段包含空值。

换句话说,稀疏索引可以使多个文档都具有null值。

sparse indexes


来自评论:

您的错误表明该密钥名为mydb.users.$email_1,这使我怀疑您在users.emailusers.local.email上都有索引(前者已经过时且未使用过)。从Mongoose模型中删除字段不会影响数据库。如果是这种情况,请与mydb.users.getIndexes()核对,并使用mydb.users.dropIndex(<name>)手动删除不需要的索引。

答案 1 :(得分:50)

如果您仍处于开发环境中,我会删除整个数据库并重新开始使用新架构。

从命令行

➜ mongo
use dbName;
db.dropDatabase();
exit

答案 2 :(得分:15)

检查收集索引。

由于字段集合中的过时索引,我遇到了这个问题,这些索引应该由不同的新路径存储。

当您将字段指定为唯一时,Mongoose会添加索引。

答案 3 :(得分:11)

基本上这个错误就是说,你在特定字段上有一个唯一索引,例如:&#34; email_address&#34;,所以mongodb期望集合中每个文档的唯一电子邮件地址值。

因此,让我们先说一下,在您的架构中,未定义唯一索引,然后您使用相同的电子邮件地址或没有电子邮件地址(空值)注册了2个用户。

后来,你看到有一个错误。因此,您尝试通过向架构添加唯一索引来更正它。但是您的收藏集已经有重复项,因此错误消息显示您无法再次插入重复值。

你基本上有三个选择:

  1. 删除集合

    db.users.drop();

  2. 找到具有该值的文档并将其删除。我们假设该值为null,您可以使用以下命令将其删除:

    db.users.remove({ email_address: null });

  3. 删除唯一索引:

    db.users.dropIndex(indexName)

  4. 我希望这有助于:)

答案 4 :(得分:7)

在这种情况下,登录Mongo会找到您不再使用的索引(在OP中为“ email”)。然后选择下降索引 enter image description here

答案 5 :(得分:7)

我想向5岁的孩子解释这个问题的答案/解决方案,这样每个人都可以理解。

我有一个应用。我希望人们使用他们的电子邮件,密码和电话号码进行注册。 在我的MongoDB数据库中,我想根据他们的电话号码和电子邮件来唯一地识别人员-因此这意味着每个人的电话号码和电子邮件都必须是唯一的。

但是,有一个问题:我已经意识到每个人都有一个电话号码,但并不是每个人都有一个电子邮件地址。

那些没有电子邮件地址的人向我保证,他们下周将有一个电子邮件地址。但是我还是要他们注册-所以我告诉他们在他们将电子邮件输入字段留空的情况下继续注册他们的电话号码。

他们这样做。

我的数据库需要一个唯一的电子邮件地址字段-但是我有很多人以“ null”作为他们的电子邮件地址。因此,我转到代码中,告诉我的数据库架构允许空/空电子邮件地址字段,稍后当承诺下周将电子邮件添加到个人资料中的人时,我将使用电子邮件唯一地址填充该字段。

所以它现在对所有人都是双赢的(但是您;-]):人们注册,我很高兴拥有他们的数据...并且我的数据库很高兴,因为它被很好地使用了...但是关于你 ?我尚未向您提供构成模式的代码。

这是代码: 注意:电子邮件中的稀疏属性告诉我的数据库允许空值,之后将使用唯一值填充空值。

var userSchema = new mongoose.Schema({
  local: {
    name: { type: String },
    email : { type: String, require: true, index:true, unique:true,sparse:true},
    password: { type: String, require:true },
  },
  facebook: {
    id           : { type: String },
    token        : { type: String },
    email        : { type: String },
    name         : { type: String }
  }
});

var User = mongoose.model('User',userSchema);

module.exports = User;

我希望我已经很好地解释了。 快乐的NodeJS编码/黑客!

答案 6 :(得分:7)

我遇到了类似的问题, 我只需清除特定字段的索引,然后它就可以为我工作。 https://docs.mongodb.com/v3.2/reference/method/db.collection.dropIndexes/

答案 7 :(得分:4)

这是我的相关经历:

在'User'模式中,我将'name'设置为唯一键,然后运行一些执行,我认为已经设置了数据库结构。

然后我将唯一键更改为'username',并且在将数据保存到数据库时不再传递'name'值。因此,mongodb可以自动将新记录的“name”值设置为null,即重复键。我尝试将“name”键设置为“User”架构中的唯一键{name: {unique: false, type: String}},以覆盖原始设置。但是,它没有用。

最后,我制定了自己的解决方案:

保存数据记录时,只需设置一个不太可能与'name'键重复的随机键值。简单数学方法'' + Math.random() + Math.random()生成一个随机字符串。

答案 8 :(得分:3)

我有同样的问题。尝试调试不同的方法无法弄清楚。我尝试删除该集合,之后它运行良好。虽然如果您的馆藏有很多文件,这不是一个好的解决方案。但如果你处于早期开发状态,请尝试删除该集合。

db.users.drop();

答案 9 :(得分:2)

这是因为已经存在一个具有相同名称和配置的集合。只需通过mongo shell从mongodb中删除该集合,然后重试。

  

db.collectionName.remove()

现在运行应该运行的应用程序

答案 10 :(得分:2)

我有类似的问题,我意识到默认情况下mongo每个集合只支持一个模式。将新架构存储在其他集合中,或使用当前集合中的不兼容架构删除现有文档。或者找到一种方法,为每个集合提供多个模式。

答案 11 :(得分:2)

删除您的数据库,然后它将起作用。

您可以执行以下步骤删除数据库

步骤1:转到mongodb安装目录,默认目录为“ C:\ Program Files \ MongoDB \ Server \ 4.2 \ bin

第2步:直接启动mongod.exe或使用命令提示符将其最小化。

步骤3:直接启动mongo.exe或使用命令提示符并运行以下命令

i)使用yourDatabaseName (如果您不记得数据库名称,请使用显示数据库

ii) db.dropDatabase()

这将删除您的数据库。 现在您可以插入数据了,它不会显示错误,它将自动添加数据库和集合。

答案 12 :(得分:1)

在首次在保存时构建一些索引后从模式中删除属性后出现同样的问题。从架构中删除属性会导致非现有属性的空值,该属性仍具有索引。从头开始删除索引或从新集合开始有助于此。

注意:在这种情况下,错误消息会引导您。它有一条不再存在的路径。在我的情况下,旧路径是... $ uuid_1(这是一个索引!),但新的路径是.... * priv.uuid_1

答案 13 :(得分:1)

当我尝试修改使用mangoose定义的模式时,我遇到了同样的问题。我认为这个问题是由于创建集合时有一些基础过程的原因,比如描述对用户隐藏的索引(至少在我的情况下)。所以我找到的最佳解决方案是删除整个集合然后重新开始。

答案 14 :(得分:1)

当我的config / models.js

中有以下配置时,我遇到了同样的问题
module.exports.models = {
  connection: 'mongodb',
  migrate: 'alter'
}

更改迁移&#39;更改&#39;安全&#39;为我修好了。

module.exports.models = {
  connection: 'mongodb',
  migrate: 'safe'
}

答案 15 :(得分:1)

我有同样的问题。问题是我从模型中删除了一个字段。当我删除数据库时,它修复了

答案 16 :(得分:1)

我已经通过这种方式解决了我的问题。

只需进入您的 mongoDB 帐户 -> Atlast 集合,然后删除您的数据库列。或者转到 mongoDB compass 然后删除您的数据库,

有时当您在数据库中保存空值时会发生这种情况。

答案 17 :(得分:1)

如果您处于开发的早期阶段:消除集合。否则:将这个添加到每个给你错误的属性中(注意:我的英语不好,但我试着解释一下)

index:true,
unique:true,
sparse:true

答案 18 :(得分:1)

我也遇到了这个问题,我解决了。 此错误表明此处已经存在电子邮件。因此,您只需要从“电子邮件模型”属性中删除此行即可。

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<head>
    <title>Hello!</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <!-- import the webpage's stylesheet -->
    <link rel="stylesheet" href="/style.css">
    
    <!-- import the webpage's javascript file -->
    <script src="/jquery-3.3.1.min.js"></script>
    <script src="/script.js" defer></script><!---this script i have written in js part of snippset"-->
    <script>
   // alert($(".outdiv a").text());
    
    </script>
  </head>  
  <body>
    <h1>Hi there!</h1>
    
    <p>
      I'm your cool new webpage. Made with <a href="https://glitch.com">Glitch</a>!
    </p>
    <div class="outdiv">
      
      
    </div>

    <!-- include the Glitch button to show what the webpage is about and
          to make it easier for folks to view source and remix -->
    <div class="glitchButton" style="position:fixed;top:20px;right:20px;"></div>
    <script src="https://button.glitch.me/button.js"></script>
  </body>
</html>

即使它不起作用,也有可能。因此,只需要从MongoDB中删除集合,然后重新启动服务器即可。

答案 19 :(得分:1)

这不是什么大问题,但是像我这样的初学者级开发人员,我们要弄清楚这是什么错误,最后我们浪费了大量时间来解决它。

实际上,如果您删除数据库并再次创建数据库,并且在尝试创建集合之后,它将可以正常工作。

➜ mongo
use dbName;
db.dropDatabase();
exit

答案 20 :(得分:0)

只需删除该特定索引,而不是删除数据库或集合。

db.users.dropIndex("email_1")

答案 21 :(得分:0)

我在社交媒体注册时在我的项目中遇到了同样的问题。当用户首次使用电子邮件加入工作时没有任何问题。当另一个用户使用电子邮件注册时,由于分配给社交媒体 ID 的空值而出现问题。原因是根据唯一真实约束,应该只允许一个用户插入空值。

错误架构:

facebookId: {
    type: String,
    index:true
  },

解决方案架构:

  1. 删除针对 facebookId 创建的现有索引 db.users.dropIndex(facebookid_)

2) 当我们使用 sparse: true 属性时,它允许我们存储多个空值

  facebookId: {
    type: String,
    index:true,
    unique:true,
    sparse:true
  },

答案 22 :(得分:0)

mongoDB Atlas 在其集合选项卡下有一个索引选项卡,允许您查看和删除您不想要的任何索引。

答案 23 :(得分:0)

在MongoDB指南针中检查该集合的索引,并删除与该集合不相关的那些索引,或者尝试删除所有索引(不是从代码中而是从db中删除)。

答案 24 :(得分:0)

这是我在2020年9月解决同一问题的方式。mongodb地图集(云和桌面)提供了一种超快速便捷的方法。大概以前不是那么容易吗?这就是为什么我觉得我应该在2020年写下这个答案。

首先,我阅读了一些有关更改猫鼬模式中“唯一”字段的建议。如果您遇到此错误,我认为您已经更改了架构,但是尽管如此,您还是得到了500作为响应,并请注意:指定重复的KEY!。如果问题是由架构配置引起的,并且假设您已经配置了不错的中间件来记录mongo错误,则响应为400。

那是为什么?就我而言,很简单,架构上的该字段曾经只接受唯一值,但我只是将其更改为接受重复值。过去,Mongodb为该字段创建了一个索引,因此即使在架构上将“唯一”属性设置为“ false”后,mongodb仍在使用该索引。

解决方案?删除该索引。您可以在2秒钟内从Mongo Atlas完成它。

转到您的收藏集。默认情况下,您位于“查找”选项卡上。只需选择右侧的下一个:“索引”。您将看到仍然有给同一字段的索引给您带来麻烦。只需点击“下降索引”按钮即可。

我认为这比删除整个收藏集更好。基本上是因为这是为什么它在删除整个集合后仍然可以工作的原因。因为如果您的第一个条目使用带有“ unique:false”的新架构,mongo不会设置索引。

Server response

Cloud Atlas

答案 25 :(得分:0)

我面临着类似的问题,根据我的理解,我去清理了idexes并重新启动服务器,并且可能在这里提到的几乎所有内容仍然存在错误,如果我正在使用,我传递的jsonwebtoken秘密密钥是未定义的jsonwebtoken,请检查一次

答案 26 :(得分:0)

对于未来的开发人员,我建议使用指南针删除INDEX TAB中的索引...这不会删除您的收藏集Manage Indexes

中的任何文档

答案 27 :(得分:-1)

更改集合名称(如果它已经存在于数据库中),它将显示错误。而且,如果您将任何属性赋予为唯一属性,则会发生相同的错误。

答案 28 :(得分:-1)

您的数据库中已存在具有该 ID 号的文档。确保始终为尝试放入数据库的每个新文档设置唯一 ID。例如:

instanceOfCustomObjDocument.setMyDocId(serviceInstance.getSequenceNumber(CustomObjDocument.SEQUENCE_NAME));

以下是如何为 Spring + MongoDB Tech Stack 设置序列 ID 的示例代码: https://github.com/Java-Techie-jt/mongo-sequence-id-example

https://www.youtube.com/watch?v=x980d_aFJ2s

答案 29 :(得分:-2)

有同样的问题我通过删除属性上的unique属性来解决它。

只需找到另一种方法来验证或检查架构的唯一属性值。

答案 30 :(得分:-5)

请清除收集或从MongoDB数据库中删除整个集合,稍后再试。