前言
此篇博文是 Mongdb 基础系列之一;主要介绍 MongoDB 的数据建模相关内容;
本文为作者的原创作品,转载需注明出处;
简介
Document Validation 是 3.2 以后加入的内容,
MongoDB provides the capability to validate documents during updates and insertions. Validation rules are specified on a per-collection basis using the validator option, which takes a document that specifies the validation rules or expressions. Specify the expressions using any query operators, with the exception of $near, $nearSphere, $text, and $where.
MongoDB 提供了对文档进行更新
和插入
的验证规则;一个验证规则是作用在一个 collection 上
;验证规则是通过 validator 选项进行创建的,它将会为每一个文档创建相关的 validation rules expressions (验证规则表达式);可以使用任何的 query operators 来定义此验证规则表达式,但是除了 $near, $nearSphere, $text, and $where 以外;
另外注意两个非常重要的 options,既 validationLevel option 和 validationAction option;validationLevel option 将会控制如何对已经存在的 documents 进行验证;validationAction option
如何添加验证规则
对已经存在的 collection 添加验证规则
对已经存在的 collection,使用命令 collMod 来为其创建验证规则;比如,
1 | db.runCommand( { |
上述命令既是对已经存在的 contacts collection 添加验证规则;
在新建的 collection 的时候添加验证规则
如果是新建 collection,可以使用 db.createCollection() 命令为其创建验证规则,就像下面这样,
1 | db.createCollection( "contacts", |
可见,在创建 collection 的时候,指定可选项 validator 即可为其创建验证规则;
重要的 Options
validationLevel option
validationLevel 选项表示如何对已经存在的 documents 进行验证;默认是strict
,表示对所有已经存在的 documents 均要进行验证;可以将其设置为moderate
,表示如果文档中的字段匹配了验证规则中所定义的字段,才进行验证,若是没有匹配,则不验证;看下面这个例子,
假设我们有 contacts 这样一个 collection,包含两个 documents,
1 | { |
注意,这两个 document 的字段并不相同,第二个 document 只有第一个 document 字段的一部分;我们为该 collection 添加 validation rules,如下,
1 | db.runCommand( { |
这里我们将 validationLevel 设置为moderate
,如果你对 _id: 125876 进行更新操作,则验证规则将会作用到该 document 上;但是如果你对 _id: 860000 进行更新操作,验证规则将不会作用到该 document 上;
如果你想要彻底的禁用验证功能,则将 validationLevel 设置为off
即可;
validationAction option
validationAction option 决定了如何对违反了验证规则的 documents 进行处理;
默认情况下,validationAction 的默认值是error
,表示在 insertion 或者是 udpate documents 的时候,拒绝
任何违反了验证规则的 documents;如果将 validationAction 的设置为warn
,它只在日志中通过警告的方式记录这些违规操作,但是仍然会插入或更新这些 documents;
看下面这个例子,
1 | db.createCollection( "contacts", |
如上所述,我们对 contacts collection 的三个字段分别定义了三个不同的验证规则,并且将 validationAction 设置为warn
;然后我们写入一个非法的 documents,
1 | db.contacts.insert( { name: "Amanda", status: "Updated" } ) |
很明显,该 document 的 status 字段不合法,该字段只允许两种状态既 Unknown 和 Incomplete;但是,因为这里的级别是warn
,所以它仍然可以插入成功,但是日志中会包含该警告日志,如下
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" } |
一些重要的限制
You cannot specify a validator for collections in the admin, local, and config databases.
You cannot specify a validator for system. collections.
绕开文档验证
用户可以通过使用 bypassDocumentValidation 选项来绕开文档验证;这些命令可以支持 bypassDocumentValidation 选项;
For deployments that have enabled access control, to bypass document validation, the authenticated user must have bypassDocumentValidation action. The built-in roles dbAdmin and restore provide this action.
针对已经启动访问控制的部署实例,要想绕开文档验证,具有权限的用户必须拥有 bypassDocumentValidation 的权限;内置的 dbAdmin 和 restore 默认拥有此权限;