当前位置:   article > 正文

mongodb3.4 Document Validation【文档验证】_mongodb bypassdocumentvalidation

mongodb bypassdocumentvalidation

环境

mongodb:3.4

该功能是从mongodb版本 3.2开始支持的.

@author 喻涛

概述

本篇由本人翻译官方文档:
https://docs.mongodb.com/manual/core/document-validation/


Mongodb提供了在插入和更新时验证文档的功能。每个集合都是基于使用validator选项来指定验证规则的。该验证器选项是给文档指定验证规则或表达式。
可以使用任何查询操作来指定表达式, 除了$near,$nearSphere, $text,$where

使用collMod命令和validator选项给已经存在的集合添加文档验证。
你也可以使用db.createCollection()validator 选项在创建新集合时,指定文档校验规则。如下:

db.createCollection( "contacts",
   { validator: { $or:
      [
         { phone: { $type: "string" } },
         { email: { $regex: /@mongodb\.com$/ } },
         { status: { $in: [ "Unknown", "Incomplete" ] } }
      ]
   }
} )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

MongoDB也提供了validationLevel选项,该选项决定了在对现有的文件进行更新时,MongoDB应用验证规则的严格程度。validationAction 选项,其决定了MongoDBerror,会拒绝违反验证规则的文档. 为warn时,记录违反规则的行为但是允许无效文档.也就是即使违反规则,更新操作依然会执行.

行为,表现

验证是在更新插入时发生的。当你给一个集合添加验证时, 早已存在的文档不会进行验证除非你对其(早已存在的文档)进行修改(即:更新操作)。

现有文档

你可以使用validationLevel 选项控制MongoDB如何处理现有的文档。

validationLevel默认指 strictMongoDB会给所有的插入更新操作应用校验规则。把validationLevel设置为moderateMongoDB会在对现有符合验证标准的文档执行插入更新时,应用验证规则。使用moderate级别, 当更新现有的文档时,不会去检查不符合验证标准的文档的合法性。

例如:

我们有这样一个集合contacts

{
   "_id": "125876",
   "name": "Anne",
   "phone": "+1 555 123 456",
   "city": "London",
   "status": "Complete"
},
{
   "_id": "860000",
   "name": "Ivan",
   "city": "Vancouver"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

使用下面的命令给contacts集合添加验证规则:

db.runCommand( {
   collMod: "contacts",
   validator: { $or: [ { phone: { $exists: true } }, { email: { $exists: true } } ] },
   validationLevel: "moderate"
} )
  • 1
  • 2
  • 3
  • 4
  • 5

contacts集合现在有个验证器和validationLevelmoderate级别。 如果你试图更新_id:125876的文档, MongoDB将应用验证规则,因为这个文档符合标准。
相反, MongoDB不会把验证规则应用在更新_id:860000的文档上, 因为它不符合验证规则。

注:要使验证失效, 你可以把validationLevel设置为off

接受或拒绝无效文档

validationAction 选项决定MongoDB如何处理违反验证规则的文档。

validationAction默认是errorMongoDB将拒绝任何违反验证规则的插入更新
validationAction设置为warnMongoDB记录任何违反规则的行为, 但是插入更新操作依然会继续执行。

例如:

下面这个例子创建了一个名为contacts集合和一个验证器, 该验证器指定了插入更新文档应该至少匹配下面三个条件中一个条件。

1、phone字段为string
2、email字段匹配正则表达式
3、status字段UnknownIncomplete,两者选一。

db.createCollection( "contacts",
   {
      validator: { $or:
         [
            { phone: { $type: "string" } },
            { email: { $regex: /@mongodb\.com$/ } },
            { status: { $in: [ "Unknown", "Incomplete" ] } }
         ]
      },
      validationAction: "warn"
   }
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

使用上面的验证器,下面的插入操作验证规则会失败,因为validationActionwarn,写操作会记录失败的信息,操作依然会执行成功。

db.contacts.insert( { name: "Amanda", status: "Updated" } )
  • 1

日志包括完整的集合命名空间和不符合验证规则的文档,以及操作时间。

2015-10-15T11:20:44.260-0400 W STORAGE  [conn3] Document would fail validation collection: example.contacts doc: { _id: ObjectId('561fc44c067a5d85b96274e4'), name: "Amanda", status: "Updated" }
  • 1

限制

你不能在adminlocalconfig数据库中给集合指定验证器。
你不能给system.*集合指定验证器。

绕过验证器

用户可以使用bypassDocumentValidation选项来绕过验证器。关于支持bypassDocumentValidation选项的命令列表,参考Document Validation

这里我也列出来:

command
applyOps命令
findAndModify命令和db.collection.findAndModify()方法
mapReduce命令和db.collection.mapReduce()方法
insert命令
update命令
aggregate命令中的$out和db.collection.aggregate()方法

对于已经开启访问控制的部署服务器,通俗点就是已经上线并开启访问控制的MongoDB服务器。为了绕过文档验证,认证用户必须具有bypassDocumentValidation的操作。内置角色dbAdminrestore提供了此操作。

总结

validationLevel:作用就是决定哪些文档符合验证规则。
validationAction:要是有不符合规则的文档,该怎么去处理。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/286892
推荐阅读
相关标签
  

闽ICP备14008679号