下面是我的用户模式在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中有一个条目


当前回答

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

index:true,
unique:true,
sparse:true

其他回答

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

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

然而,有一个问题:我发现每个人都有电话号码,但不是每个人都有电子邮件地址。

那些没有电子邮件地址的人已经向我保证他们下周会有一个电子邮件地址。但我还是想让他们注册——所以我告诉他们继续注册他们的电话号码,因为他们的电子邮件输入字段是空的。

他们这样做。

我的数据库需要一个唯一的电子邮件地址字段-但我有很多人用“空”作为他们的电子邮件地址。所以我在我的代码中告诉我的数据库模式允许空/空的电子邮件地址字段,当那些承诺下周将电子邮件添加到他们的个人资料的人时,我将用电子邮件唯一地址填充这些字段。

所以现在对每个人来说都是双赢(除了你;-]):人们注册,我很高兴有他们的数据…我的数据库很高兴,因为它被很好地使用……但是你呢?我还没有给出创建模式的代码。

代码如下: 注意:在电子邮件中的稀疏属性,是什么告诉我的数据库允许空值,稍后将被填充为唯一的值。

var userSchema =新的猫鼬。模式({ 本地:{ 名称:{类型:字符串}, email:{类型:字符串,要求:true,索引:true,唯一:true,稀疏:true}, 密码:{类型:字符串,要求:true}, }, facebook: { id:{类型:字符串}, token:{类型:字符串}, email:{类型:字符串}, 名称:{类型:字符串} } }); var User = mongoose.model('User',userSchema); 模块。出口=用户;

我希望我已经解释清楚了。 NodeJS编码/破解快乐!

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

相关文件:

If a document does not have a value for the indexed field in a unique index, the index will store a null value for this document. Because of the unique constraint, MongoDB will only permit one document that lacks the indexed field. If there is more than one document without a value for the indexed field or is missing the indexed field, the index build will fail with a duplicate key error. You can combine the unique constraint with the sparse index to filter these null values from the unique index and avoid the error.

唯一索引

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

换句话说,稀疏索引适用于多个文档都具有空值的情况。

稀疏索引


评论:

您的错误显示键名为mydb.users。$email_1,这使我怀疑您有两个用户的索引。email和users.local.email(前者是旧的,目前未使用)。从Mongoose模型中删除字段不会影响数据库。检查mydb.users.getIndexes(),如果是这种情况,用mydb.users.dropIndex(<name>)手动删除不需要的索引。

以下是我的相关体会:

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

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

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

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

在这种情况下,登录到Mongo,找到你不再使用的索引(在OP的情况下是'email')。然后选择删除索引

在首先在保存时建立一些索引之后,从模式中删除属性也会出现同样的问题。从模式中删除属性会导致一个不存在的属性的空值,该属性仍然有索引。在这里,删除索引或从头开始一个新的集合会有所帮助。

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