下面是我的用户模式在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集合,没有这样的重复条目存在,让我知道我做错了什么?

供您参考- req.body.email和req.body.password是抓取值。

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

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


当前回答

编辑:这个解决方案在2023年仍然有效,你不需要丢弃你的收集或丢失任何数据。

以下是我在2020年9月解决同样问题的方法。有一个超级快速和简单的方法从mongodb图集(云和桌面)。可能以前没那么容易吧?这就是为什么我觉得我应该在2020年写下这个答案。

首先,我阅读了上面关于在mongoose模式上更改字段“unique”的一些建议。如果遇到这个错误,我假设您已经更改了模式,但尽管如此,您还是得到了一个500作为响应,并注意:指定重复的KEY!如果问题是由模式配置引起的,并且假设您已经配置了一个不错的中间件来记录mongo错误,那么响应将是400。

为什么会发生这种情况(至少是主要原因)

为什么呢?在我的例子中很简单,模式上的字段过去只接受唯一的值,但我只是将其更改为接受重复的值。Mongodb为具有唯一值的字段创建索引,以便更快地检索数据,因此在过去mongo为该字段创建了索引,因此即使在schema上设置“unique”属性为“false”后,Mongodb仍然使用该索引,并将其视为必须是唯一的。

如何解决

放弃这个指数。你可以在2秒内从Mongo Atlas或在Mongo shell上执行命令。为了简单起见,我将为不使用mongo shell的用户展示第一个。

去看看你的收藏。默认情况下,你在“查找”标签。只需选择右边的下一个:“Indexes”。您将看到同一个字段的索引仍然会给您带来麻烦。只需点击按钮“下降指数”。完成了。

因此,不要每次出现这种情况时都丢弃数据库

我相信这是一个更好的选择,而不仅仅是放弃整个数据库甚至是收藏。基本上是因为这就是为什么它在放弃整个集合后仍然有效。因为如果你的第一个条目使用你的新模式unique: false, mongo不会为这个字段设置索引。

其他回答

检查收集索引。

我有这个问题,由于过时的索引收集字段,这应该由不同的新路径存储。

猫鼬添加索引,当你指定字段为唯一的。

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

假设,在您的模式中,前面没有定义唯一索引,然后您使用相同的电子邮件地址或没有电子邮件地址(空值)注册了2个用户。

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

你基本上有三个选择:

删除集合 db.users.drop (); 找到具有该值的文档并删除它。假设该值为空,你可以使用以下命令删除它: db.users。Remove ({email_address: null}); 删除Unique索引: db.users.dropIndex (indexName)

我希望这对你有所帮助:)

我用这种方法解决了我的问题。

只需进入您的mongoDB帐户->最后收集,然后删除您的数据库列。或者使用mongoDB compass,然后删除数据库,

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

以下是我的相关体会:

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

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

最后,我提出了自己的解决方案:

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

这不是一个大问题,但像我这样的初级开发人员,我们知道这是什么样的错误,最后我们花了很长时间来解决它。

实际上,如果你删除数据库并再次创建数据库,然后尝试创建集合,那么它将正常工作。

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