猫鼬,默认设置为null和唯一

mda*_*sh1 6 mongoose mongodb node.js

我正在尝试创建一个具有“ facebookid”键的用户架构,这是一个唯一值,仅当用户使用facebook进行注册时才给出,而不是当用户通过google或本地进行注册时才给出。当用户在本地注册时,默认将facebookid设置为null。但是我得到了错误:'insertDocument :: caused by :: 11000 E11000 duplicate key error index: db22.users.$facebookid_1 dup key: { : null }'

这是模式:

let UserSchema = new Schema({
    facebookid: {
        type: String,
        required: false, // only required for facebook users
        unique: true,
        default: null
    },
    // more details + keys below ...
})
Run Code Online (Sandbox Code Playgroud)

因此,如果我还希望条目唯一,那么如果值为null,如何允许重复的条目用于facebookfacebookid?

即我不想看到两个类似的String条目:
不好:

* User: {_id: 123, facebookid: '4325',username:'joe'}
* User: {_id: 432, facebookid: '4325', username: 'pat'}
Run Code Online (Sandbox Code Playgroud)

好的:

* User: {_id: 123, facebookid: null,username:'joe'}
* User: {_id: 432, facebookid: null, username: 'pat'}
Run Code Online (Sandbox Code Playgroud)

Mik*_*kaS 9

您可以使用partialFilterExpressions

facebookid: {
  type: String,
  required: false, // only required for facebook users
  index: {
    unique: true,
    partialFilterExpression: { facebookid: { $type: 'string' } },
  },
  default: null,
 }
Run Code Online (Sandbox Code Playgroud)

这使null可以多次使用。

请记住,在更改唯一约束之后,重新启动Mongoose和所有其他操作。如果还没有,请参阅问题。


Sha*_*Roy 2

对于这种情况,您不应该unique: true在模式中使用,但您必须检查facebookid是否已经存在,以便您可以添加facebookid使用验证schemaName.path并检查唯一性。就像下面这样。

let UserSchema = new Schema({
    facebookid: {
        type: String,
        required: false,
        default: null
    },
    // more details + keys below ...
})

UserSchema.path('facebookid').validate(function(value, next){
  if(!value) {
    return next();
  }
  // I assueme your model name is User
  mongoose.models['User'].findOne({facebookid: value }, function(err, found){
    if(err){
      return next(false);
    }

    if(found && found.facebookid){
      return next(false, "Already exist this facebook ID");
    }else{
      return next();
    }
  });

});
Run Code Online (Sandbox Code Playgroud)