以下是我在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');


这就是我将其保存在数据库中的方式-

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集合,并且没有这样的重复条目,让我知道我在做错什么吗?

FYI-req.body.emailreq.body.password正在获取值。

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

如果我将其完全删除,则会插入文档,否则即使我在local.email中也有条目,也会引发错误“ Duplicate”错误。 >

评论

发生了同样的错误!在开发过程中,我们禁用了自动索引,并使用了小写的模式名称/键。我们后来决定改用TitleCase,但未能更新索引名称(即:titleCase而不是TitleCase)。因此,当我们启用索引功能时,就会出现此错误。花了一点时间弄清楚。您需要确保所有名称/键在任何地方都准确命名。

我遇到了相同的错误,并将猫鼬模型设置为唯一:false不会产生任何影响。我意识到我必须先放下桌子,然后它才能工作。您可以执行db.whateverthecollection.drop({})之类的设置。请注意,它会删除该集合。

_id:添加mongoose.Types.ObjectId,因为需要唯一的ID

#1 楼

错误消息是说已经有一个以null作为电子邮件的记录。换句话说,您已经有一个没有电子邮件地址的用户。
相关文档:

如果文档在唯一索引中没有索引字段的值,则索引将为此文档存储一个空值。由于存在独特的约束,MongoDB将只允许一个缺少索引字段的文档。如果有多个文档没有索引字段的值或缺少索引字段,则索引构建将失败,并出现重复的键错误。
您可以将唯一约束与稀疏索引结合使用以过滤这些null

唯一索引

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

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

来自注释:
您的错误说该密钥名为mydb.users.$email_1,这使我怀疑您在users.emailusers.local.email上都具有索引(该索引现在很旧并且尚未使用)。从猫鼬模型中删除字段不会影响数据库。使用mydb.users.getIndexes()检查是否是这种情况,并使用mydb.users.dropIndex(<name>)手动删除不需要的索引。

评论


我只是删除了该空文档,它起作用了:) +1 ..thx寻求帮助

– Trialcoder
14年6月26日在12:28

您的错误表明该密钥名为mydb.users。$ email_1,这使我怀疑您在users.email和users.local.email上都有一个索引(当前该索引较旧且尚未使用)。从猫鼬模型中删除字段不会影响数据库。如果是这种情况,请与mydb.users.getIndexes()检查,并使用mydb.users.dropIndex()手动删除不需要的索引。

– RickN
14年6月26日在13:51

或在进行多个索引更改时使用db.users.dropIndexes()

–cs_stackX
2014年8月31日下午5:35

当我使用mongoose插件Passport-local-mongoose而不为新用户设置用户名时,这对我来说是个问题。

–sshow
16年1月23日在22:38

这是一个问题或观点,甚至是观点,@ titoih-是空值还是缺少值就像其他值一样是值还是特殊情况? “ a@b.c”和“ a@b.c”是相同的,“没有”和“没有”也一样吗?对于非稀疏索引,在MongoDB中答案为“是”。其他数据库(例如MySQL)会说“否”。

– RickN
4月26日20:33

#2 楼

如果您仍处于开发环境中,那么我将删除整个数据库,并从新的架构开始。

从命令行

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


评论


我认为此解决方案非常激进,我认为使用db.collection.dropIndexes()就足够了,如cs_stackX所说

– JorgeGarza
16年1月25日在23:15

@JorgeGarza我有同样的问题。我刚刚放下收藏夹,此后一切正常。

– Sandip Subedi
16年12月28日在4:59

我不小心用两个字段的唯一ID初始化了集合。后来,当我想使用相同的ID添加多个文档时,直到删除集合并重新访问它,我才让我这样做。

–梅尔·斯奈德(Meir Snyder)
18年2月5日在16:13

如果您是开发的新手,这是一个很好的机会进行实验并弄清楚如何解决此问题...而不是一旦您已经存储了千兆字节的用户数据就遇到此问题

–贾纳克·梅纳(Janac Meena)
18年6月5日在14:20

@JorgeGarza的评论很有道理。重新启动服务器后,删除的索引将由架构文件再次重建。此外,它也起作用。

–retr0
19年1月7日在10:02

#3 楼

检查集合索引。

我遇到了这个问题,因为字段的集合索引过时,应该通过其他新路径存储。

当您指定字段时,猫鼬会添加索引一样独特。

#4 楼

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

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

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

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

他们这样做。

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

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

这里是代码:
注意:email中的稀疏属性告诉我数据库允许空值,稍后将用唯一值填充。




 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编码/黑客!

评论


如果您需要稀疏索引和唯一验证,并且不需要其他字段,则需要使用partialFilterExpression选项。看到这个答案stackoverflow.com/a/34600171/728287

– Gianfranco P.
19年10月2日在10:03

#5 楼

好吧,基本上这个错误就是说,您在特定字段上具有唯一索引,例如:“ email_address”,因此mongodb希望集合中每个文档的唯一电子邮件地址值。

所以,在方案的早期,未定义唯一索引,然后您使用相同的电子邮件地址或没有电子邮件地址(空值)的2个用户进行了注册。

后来,您发现有一个错误。因此您尝试通过向架构添加唯一索引来更正它。但是您的集合已经有重复项,因此错误消息表明您不能再次插入重复值。

您实际上具有三个选项:


< br拖放集合

db.users.drop();


查找具有该值的文档并将其删除。假设该值为空,则可以使用以下命令将其删除:

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


删除唯一索引:

db.users.dropIndex(indexName)


希望对您有所帮助:)

#6 楼

我遇到了类似的问题,
我只需清除特定字段的索引,然后对其使用即可。
https://docs.mongodb.com/v3.2/reference/method/db.collection.dropIndexes /

#7 楼

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


#8 楼

这是我的丰富经验:

在“用户”模式中,我将“名称”设置为唯一键,然后运行一些执行,我认为这已经建立了数据库结构。

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

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

仅设置一个随机键值,该值在出现以下情况时可能不会与“ name”键重复您保存数据记录。只需使用数学方法'' + Math.random() + Math.random()即可生成随机字符串。

评论


我认为这不是一个有效的解决方案,只是掩盖了问题。

–里克
15年9月13日在14:53

丑陋但务实

–安东尼
17-10-22在7:02

#9 楼

我遇到过同样的问题。尝试调试不同的方式无法解决。我尝试删除该集合,之后效果很好。如果您的收藏集中有很多文档,这不是一个好的解决方案。但是,如果您处于开发的早期阶段,请尝试删除该集合。

db.users.drop();


#10 楼

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


db.collectionName.remove()


现在运行您的应用程序,它应该可以运行

#11 楼

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

#12 楼

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

unique: true


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

#13 楼

删除数据库,然后它将起作用。
您可以执行以下步骤来删除数据库
步骤1:转到mongodb安装目录,默认目录为“ C:\ Program Files \ MongoDB \ Server \ 4.2 \ bin“
步骤2:直接启动mongod.exe或使用命令提示符并将其最小化。
步骤3:直接启动mongo.exe或使用命令提示符并运行以下命令

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


ii)db.dropDatabase()

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

#14 楼

当我在config / models.js中进行以下配置时,也遇到了同样的问题。更改从'alter'到'safe'的迁移为我修复了它。

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


#15 楼

在首先在保存时建立一些索引后,从架构中删除属性后出现相同的问题。从架构中删除属性会导致不存在的属性(仍具有索引)的值为空。删除索引或从头开始创建新集合会有所帮助。

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

#16 楼

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

#17 楼

这不是什么大问题,但像我这样的初学者水平的开发人员,我们要弄清楚这是什么错误,最后我们花了很多时间解决它。
实际上,如果您删除数据库并再次创建数据库,然后再尝试创建集合,它将可以正常工作。
➜ mongo
use dbName;
db.dropDatabase();
exit


#18 楼

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

#19 楼

对于未来的开发人员,我建议使用指南针删除INDEX TAB中的索引...这不会删除您的收藏夹中的任何文档管理索引

#20 楼

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

#21 楼

这就是我在2020年9月解决同一问题的方式。mongodb地图集(云和桌面)提供了一种超快速便捷的方法。大概以前不是那么容易吗?这就是为什么我觉得我应该在2020年写出这个答案。
首先,我读了一些关于更改猫鼬模式中“唯一”字段的建议。如果您遇到此错误,我认为您已经更改了架构,但是尽管如此,您还是得到了500作为响应,并注意:指定重复的KEY!。如果问题是由架构配置引起的,并且假设您已经配置了不错的中间件来记录mongo错误,则响应为400。
为什么?就我而言,很简单,架构上的该字段曾经只接受唯一值,但我只是将其更改为接受重复值。 Mongodb过去为该字段创建了一个索引,因此即使在架构上将“ unique”属性设置为“ false”后,mongodb仍在使用该索引。
解决方案?删除该索引。您可以在2秒钟之内从Mongo Atlas进行操作。
转到您的收藏集。默认情况下,您位于“查找”选项卡上。只需选择右侧的下一个:“索引”。您将看到仍然有给该字段的索引给您带来麻烦。只需单击“下降索引”按钮。
我相信,这比删除整个收藏集更好。基本上是因为这是为什么它在删除整个集合后仍然可以工作的原因。因为如果您的第一个条目使用带有“ unique:false”的新架构,则mongo不会设置索引。



#22 楼

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

#23 楼

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

#24 楼

遇到相同的问题,我通过删除属性上的unique属性解决了该问题。

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

评论


您应该在解决方案中提供一个示例。

–乔什·亚当斯(Josh Adams)
18年2月2日在22:40

首先清除集合和/或从mongo数据库删除整个集合是可行的,但这是一个临时解决方案。即使它们具有不同的ID,创建具有相似值的另一条记录仍然会导致E11000重复键错误。我想允许该属性的重复值,所以我只是删除了唯一属性。

– davyCode
18年2月3日在15:04

#25 楼

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

评论


那可能会让你被解雇!

–GaddMaster
11月2日15:35