Mongoose Schema vs Mongo Validator

时间:2016-04-06 01:16:21

标签: node.js mongodb validation mongoose schema

Mongo 3.2有文档验证,我们可以使用相同的方法来定义模式,而不是使用mongoose这样做。例如:

猫鼬

userschema = mongoose.Schema({
   org: String,
   username: String,
   fullname: String, 
   password: String,
   email: String
});

MongoDB的

db.createCollection(
   "example",{
     validator:{
       $and:[
         { "org":{$type:"string"}},
         { "username":{$type:"string"}},
         { "fullname":{$type:"double"}},
         {"password":$type:"string"}},
         {"email":{$type:"string"}}
       ]
     }, 
     validationLevel:"strict",
     validationAction:"error"
 })

这些两者之间的差异是什么?我们可以使用验证器提供可选字段吗?

2 个答案:

答案 0 :(得分:7)

我使用两者都是因为它们各有不同的限制:

  • Mongoose验证程序不会在所有类型的更新查询上运行,验证程序仅在更新文档中具有值的路径上运行,因为验证程序无法知道是否已经定义了必填字段在数据库中但不在客户的内存中(参见issue)。 这是使用MongoDB验证器的一个主要原因[除了Mongoose验证器]。

      

    更新验证程序仅在$set$unset操作(&$push$addToSet> = 4.8.0)上运行。

    因此,您可以在Mongoose架构中使用required: true字段,但update操作实际上不需要该字段! MongoDB验证器可以解决这个问题:

    db.runCommand({collMod: "collection", validator: {myfield: {$exists: true}}})
    
  • MongoDB大部分在验证过程中无法引用其他字段。例如,您不能说{field1: {$lte: field2}}。 Mongoose验证器可以引用其他字段。

    您可以执行一些非常基本类型的跨域引用:

    {validator: {myfield1: "Value 1", $and: [/* other validators */]}
    

    如果您使用的是Mongoose鉴别器(继承)并且对每种子类型有不同的要求,这会派上用场。

  • MongoDB不提供" nice"验证失败时的错误;它只是说writeError: {code: 121, errmsg: "Document failed validation}之类的东西。 Mongoose通常会说Path 'foo.bar' failed validation

他们分享的能力:

  • 类型验证。 Mongoose尝试将值强制转换为模式中指定的类型。具有$type属性的MongoDB将在类型不匹配的情况下导致验证失败。

  • 最小和最大数值。 Mongoose在架构上使用minmax属性。 MongoDB使用$lt$lte$gt$gte

  • 字符串枚举。猫鼬使用enum: [values]。 MongoDB使用$in: [values]

  • 字符串长度验证。猫鼬:minlength: 2, maxlength: 10。 MongoDB,使用正则表达式:{fieldname: {$regex: /.{2,10}/}}

  • 数组长度验证。 Mongoose你必须使用自定义验证器。 MongoDB:{fieldName: {$size: 2}}

  • String RegExp匹配。 Mongoose你必须使用自定义验证器。

第一个要点是主要要点。 MongoDB 没有事务现在有事务(需要付费),但它确实有强大(而且便宜)的原子更新。您经常无法可靠或安全地阅读 - >改变 - >验证 - >使用MongoDB编写,因此在这些情况下使用MongoDB本机验证器至关重要。

答案 1 :(得分:1)

自从最后一个答案以来,MongoDB 4.0已经发布。

$jsonSchema功能现在比基本猫鼬模式验证器具有更多选项。 (不过,您可以在猫鼬中添加自定义验证器)。 使用allOfoneOfanyOfnot运算符可以进行复杂的匹配,类似于Mongoose鉴别器。

使用$exec命令,可以像这样比较同一文档的两个字段的值:

db.createCollection("test", {
    validator : {
        $expr : {$gte: ["$budget", "$spend"]}
    }
})

将验证字段budget的值必须大于或等于spend的值。

(示例取自mongodb documentation

MongoDB仍然存在非信息性错误消息的问题。 就个人而言,我验证我的数据客户端(如果需要检查数据库的唯一性,请向数据库发出请求)。这样,仅当进行一致的修改(有人在检查和保存之间修改了数据)时,mongodb的验证才会出错。当出现mongodb错误时,我可以简单地重新运行客户端验证,看看有什么问题。

我认为Mongoose在使用find-modify-save策略时已经习惯了它的功能,而女巫则允许使用所有功能。此策略需要使用版本控制或锁定来防止并发修改。

在进行原子更新(使用mongodb运算符,update或findAndModify)时,以mongodb验证的当前状态,我很想不使用猫鼬(或仅将其用于连接管理)