mongodb:3.4
该功能是从mongodb版本 3.2开始支持的.
@author 喻涛
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" ] } } ] } } )
MongoDB也提供了validationLevel选项,该选项决定了在对现有的文件进行更新时,MongoDB应用验证规则的严格程度。validationAction 选项,其决定了MongoDB为error,会拒绝违反验证规则的文档. 为warn时,记录违反规则的行为但是允许无效文档.也就是即使违反规则,更新操作依然会执行.
验证是在更新和插入时发生的。当你给一个集合添加验证时, 早已存在的文档不会进行验证除非你对其(早已存在的文档)进行修改(即:更新操作)。
你可以使用validationLevel 选项控制MongoDB如何处理现有的文档。
validationLevel默认指 strict,MongoDB会给所有的插入和更新操作应用校验规则。把validationLevel设置为moderate ,MongoDB会在对现有符合验证标准的文档执行插入和更新时,应用验证规则。使用moderate级别, 当更新现有的文档时,不会去检查不符合验证标准的文档的合法性。
例如:
我们有这样一个集合contacts
{ "_id": "125876", "name": "Anne", "phone": "+1 555 123 456", "city": "London", "status": "Complete" }, { "_id": "860000", "name": "Ivan", "city": "Vancouver" }
使用下面的命令给contacts集合添加验证规则:
db.runCommand( { collMod: "contacts", validator: { $or: [ { phone: { $exists: true } }, { email: { $exists: true } } ] }, validationLevel: "moderate" } )
contacts集合现在有个验证器和validationLevel为moderate级别。 如果你试图更新_id:125876的文档, MongoDB将应用验证规则,因为这个文档符合标准。
相反, MongoDB不会把验证规则应用在更新_id:860000的文档上, 因为它不符合验证规则。
注:要使验证失效, 你可以把validationLevel设置为off。
validationAction 选项决定MongoDB如何处理违反验证规则的文档。
validationAction默认是error,MongoDB将拒绝任何违反验证规则的插入和更新。
当validationAction设置为warn, MongoDB记录任何违反规则的行为, 但是插入和更新操作依然会继续执行。
例如:
下面这个例子创建了一个名为contacts集合和一个验证器, 该验证器指定了插入和更新文档应该至少匹配下面三个条件中一个条件。
1、phone字段为string
2、email字段匹配正则表达式
3、status字段Unknown和Incomplete,两者选一。
db.createCollection( "contacts", { validator: { $or: [ { phone: { $type: "string" } }, { email: { $regex: /@mongodb\.com$/ } }, { status: { $in: [ "Unknown", "Incomplete" ] } } ] }, validationAction: "warn" } )
使用上面的验证器,下面的插入操作验证规则会失败,因为validationAction是warn,写操作会记录失败的信息,操作依然会执行成功。
db.contacts.insert( { name: "Amanda", status: "Updated" } )
日志包括完整的集合命名空间和不符合验证规则的文档,以及操作时间。
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" }
你不能在admin、local和config数据库中给集合指定验证器。
你不能给system.*集合指定验证器。
用户可以使用bypassDocumentValidation选项来绕过验证器。关于支持bypassDocumentValidation选项的命令列表,参考Document Validation
这里我也列出来:
command |
---|
applyOps命令 |
findAndModify命令和db.collection.findAndModify()方法 |
mapReduce命令和db.collection.mapReduce()方法 |
insert命令 |
update命令 |
aggregate命令中的$out和db.collection.aggregate()方法 |
对于已经开启访问控制的部署服务器,通俗点就是已经上线并开启访问控制的MongoDB服务器。为了绕过文档验证,认证用户必须具有bypassDocumentValidation的操作。内置角色dbAdmin和restore提供了此操作。
validationLevel:作用就是决定哪些文档符合验证规则。
validationAction:要是有不符合规则的文档,该怎么去处理。