Mongoose,将默认设置为 null 和唯一

Posted

技术标签:

【中文标题】Mongoose,将默认设置为 null 和唯一【英文标题】:Mongoose, set default to null and unique 【发布时间】:2018-05-04 13:54:31 【问题描述】:

我正在尝试创建一个具有“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 ...
)

如果我还希望条目是唯一的,如果值为 null,我如何允许键 facebookid 的重复条目?

即我不想看到两个相似的字符串条目: 不行:

* User: _id: 123, facebookid: '4325',username:'joe'
* User: _id: 432, facebookid: '4325', username: 'pat'

好的:

* User: _id: 123, facebookid: null,username:'joe'
* User: _id: 432, facebookid: null, username: 'pat'

【问题讨论】:

你必须设置唯一为false 【参考方案1】:

谢谢@Mikas!

额外奖励 - 您可以按如下方式引用嵌套键:“key1.key2”。 不幸的是,不支持 $ne(还没有?),所以你不能简单地使用:$ne: null

    key1: 
        key2: 
            type: String,
            index: 
                unique: true,
                partialFilterExpression: 
                    "key1.key2": 
                        // $ne: null,
                        $type: Schema.Types.String
                    
                ,

            ,
            default: null
        

【讨论】:

【参考方案2】:

你可以使用partialFilterExpressions:

facebookid: 
  type: String,
  required: false, // only required for facebook users
  index: 
    unique: true,
    partialFilterExpression:  facebookid:  $type: 'string'  ,
  ,
  default: null,
 

这允许 null 被多次使用。

记住在更改唯一约束后重新启动 Mongoose 和所有这些。如果您还没有,请参阅this 问题。

【讨论】:

感谢@MikaS。顺便说一句,mongo restart 没有帮助,我删除了数据库,然后它开始工作,你知道为什么吗?【参考方案3】:

对于这种情况,您不应在架构中使用 unique: true,但您必须检查 facebookid 是否已存在,以便您可以使用 schemaName.path 添加对 facebookid 的验证并检查唯一性。如下所示。

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

);

【讨论】:

以上是关于Mongoose,将默认设置为 null 和唯一的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose 为 Number 字段接受 null

Mongoose对Number字段接受null

使用 mongoose 将 mongo 对象的字段设置为空

Mongoose 将默认设置为空对象

Mongoose 将默认设置为空对象

将 Mongoose 文档中的默认日期设置为 now + [一些增量]