Mongodb重复键错误收集dup key: null
Posted
技术标签:
【中文标题】Mongodb重复键错误收集dup key: null【英文标题】:Mongodb duplicate key error collection dup key: null 【发布时间】:2018-07-26 05:18:46 【问题描述】:我正在尝试创建多个帐户。
第一个帐户始终有效,但是当我尝试创建一个新帐户时,我收到以下错误:
BulkWriteError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: db.users.$friends.userid_1 dup key: : null
第一个用户很好,包含一个空数组的朋友,正如我所希望的那样。
但没有创建下一个用户。
我该怎么做才能修复这个错误?
users 中好友的用户架构片段如下:
friends : [
userid : type: String, default: '', unique: true ,
],
friendRequests: [
userid : type: String, default: '', unique: true ,
编辑:
我一直在研究https://docs.mongodb.com/manual/core/index-unique/#unique-index-and-missing-field,但仍然无法正常工作。
编辑2:
默认情况下,它不会创建任何好友或好友请求。
EDIT3:
完整代码:
passport.use('local-signup', new LocalStrategy(
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true,
,
function(req, username, password, done)
process.nextTick(function()
console.log("doing local signup");
username = username.toLowerCase();
Account.findOne(username : username , function(err, user)
var expr = "/admin/";
if (err)
return done(err);
else if (user)
return done(null, false, 'That username is already taken.');
else if(username.length < 3 || username.length >= 12)
return done(null, false, 'Username has to be between 3 and 12 characters! :( ' + username);
else if(/^[a-zA-Z0-9- ]*$/.test(username) == false)
return done(null, false, 'You cant have any special characters!');
else if(password.length < 5 || password.length > 15)
return done(null, false, 'Password need to be 5-15 characters long!');
else
var newUser = new Account();
newUser.username = username;
newUser.password = newUser.encryptPassword(password);
newUser.save(function(err)
if (err)
throw err;
return done(null, newUser);
);
);
);
));
用户模型:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
var bcrypt = require('bcrypt-nodejs');
var UserSchema = new Schema(
username: type: String, index: unique: true ,
password: type: String,
salt: type: String,
hash: type: String,
gender : type: String, default: 'male',
friends : [
userid : type: String, default: '', unique: true ,
],
friendRequests: [
userid : type: String, default: '', unique: true ,
]
);
UserSchema.methods.encryptPassword = function(password)
return bcrypt.hashSync(password, bcrypt.genSaltSync(10));
UserSchema.methods.validPassword = function(password)
return bcrypt.compareSync(password, this.password);
module.exports = mongoose.model('Users', UserSchema);
【问题讨论】:
您确定需要friends.userid
的唯一索引吗?这意味着一个人最多可以成为其他人的朋友。那你在塑造一个相当孤独的世界。
哦,你是对的@AlexBlex,我的想法是用户 ID 必须是唯一的。
这是公平的限制。人是非常独特的个体。唯一约束应该在 id 属性上的用户模式上。如果你使用默认的_id
它已经是唯一的了。
删除之前创建的索引?
@AlexBlex 现在更新了。查看之前的评论
【参考方案1】:
如comment
中所述,Mongodb 不会强制单个文档内数组值的唯一性。
因此,您必须处理客户端代码中数组的唯一性。您可以使用组合策略来处理您的需求。
在创建/更新文档时,首先删除唯一索引并使用Mongoose unique array plugin
让猫鼬检查数组中的唯一性。
该插件适用于标量和文档数组。对于您的情况,您可以进行以下更改。
var uniqueArrayPlugin = require('mongoose-unique-array');
UserSchema.plugin(uniqueArrayPlugin);
这将通过验证器强制验证,并在您执行更新/保存操作时显示验证消息。
如博客中所述,当您在更新查询中使用 $push
时,独特的插件不起作用。
你可以使用
Account.findOne("friends.userid":"$ne":inputuserid, "$push":"friends":new user doc);
阅读作者的blog
和usage examples
了解更多信息。
【讨论】:
以上是关于Mongodb重复键错误收集dup key: null的主要内容,如果未能解决你的问题,请参考以下文章
MongoError:E11000 重复键错误集合:workflow.compnies 索引:username_1 dup key: username:null
使用空数组添加新用户记录时出现“E11000 重复键错误收集”