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);

阅读作者的blogusage examples 了解更多信息。

【讨论】:

以上是关于Mongodb重复键错误收集dup key: null的主要内容,如果未能解决你的问题,请参考以下文章

MongoError:E11000 重复键错误集合:workflow.compnies 索引:username_1 dup key: username:null

如何避免mongodb中的重复键错误收集

MongoDB dup key:{:null}

使用空数组添加新用户记录时出现“E11000 重复键错误收集”

Object.keys() 从集合中返回 MongoDB 对象上的意外键 [重复]

mongodb删除某字段重复的操作