以下是模型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.email
并且req.body.password
正在获取价值.
我也检查了这篇文章,但没有帮助STACK LINK
如果我完全删除然后它插入文档,否则它会抛出错误"重复"错误,即使我在local.email中有一个条目
检查收集索引.
我有这个问题,因为字段集合中的过时索引应该由不同的新路径存储.
当您将字段指定为唯一时,Mongoose会添加索引.
基本上这个错误就是说,你在特定字段上有一个唯一的索引,例如:"email_address",所以mongodb期望集合中每个文档的唯一电子邮件地址值.
因此,我们可以说,在您的架构中,未定义唯一索引,然后您使用相同的电子邮件地址或没有电子邮件地址(空值)注册了2个用户.
后来,你看到有一个错误.因此,您尝试通过向架构添加唯一索引来更正它.但是您的集合已经有重复项,因此错误消息表明您无法再次插入重复值.
你基本上有三个选择:
删除集合
db.users.drop();
找到具有该值的文档并将其删除.假设值为null,您可以使用以下命令将其删除:
db.users.remove({ email_address: null });
删除唯一索引:
db.users.dropIndex(indexName)
我希望这有帮助:)
我想解释这个问题的答案/解决方案就像我向一个5岁的孩子解释一样,所以每个人都能理解.
我有一个app.I希望人们注册他们的电子邮件,密码和电话号码.在我的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;
错误消息说已经有一个记录null
作为电子邮件.换句话说,您已经拥有一个没有电子邮件地址的用户.
相关文件:
如果文档没有唯一索引中索引字段的值,则索引将为此文档存储空值.由于唯一约束,MongoDB只允许一个缺少索引字段的文档.如果有多个文档没有索引字段的值或缺少索引字段,则索引构建将失败并出现重复键错误.
您可以将唯一约束与稀疏索引结合使用,以从唯一索引中过滤这些空值并避免错误.
独特的索引
稀疏索引仅包含具有索引字段的文档的条目,即使索引字段包含空值也是如此.
换句话说,稀疏索引可以使多个文档都具有null
值.
稀疏索引
来自评论:
你的错误说密钥被命名mydb.users.$email_1
,这让我怀疑你有两个索引users.email
和users.local.email
(前者是旧的和目前未使用的).从Mongoose模型中删除字段不会影响数据库.检查mydb.users.getIndexes()
是否是这种情况,并手动删除不需要的索引mydb.users.dropIndex(<name>)
.
我遇到了类似的问题,我只是清除特定字段的索引,然后它的工作对我来说. https://docs.mongodb.com/v3.2/reference/method/db.collection.dropIndexes/
如果您仍在开发环境中,我会删除整个数据库并重新开始使用新模式.
从命令行
? mongo use dbName; db.dropDatabase(); exit