指定校验规则
如果创建新 collection 时要指定校验规则,需要在使用 db.createCollection()
(opens new window)时指定 validator
选项。如果要将 document 校验添加到现有 collection 中,需要使用带有 validator
选项的 collMod
(opens new window)命令。MongoDB 还提供以下相关选项:
validationLevel
选项(用于确定 MongoDB 在更新过程中,对现有 document 应用校验规则的严格程度)validationAction
选项(用于确定 MongoDB 发现违反校验规则的 document 时,是选择报错并拒绝,还是接受数据但在日志中告警)。
JSON Schema
从 3.6 版本开始,MongoDB 开始支持 JSON Schema 校验。可以通过在 validator 表达式中使用 $jsonSchema
(opens new window)操作来指定 JSON Schema 校验。
db.createCollection('students', {
validator: {
$jsonSchema: {
bsonType: 'object',
required: ['name', 'year', 'major', 'address'],
properties: {
name: {
bsonType: 'string',
description: 'must be a string and is required',
},
year: {
bsonType: 'int',
minimum: 2017,
maximum: 3017,
description: 'must be an integer in [ 2017, 3017 ] and is required',
},
major: {
enum: ['Math', 'English', 'Computer Science', 'History', null],
description: 'can only be one of the enum values and is required',
},
gpa: {
bsonType: ['double'],
description: 'must be a double if the field exists',
},
address: {
bsonType: 'object',
required: ['city'],
properties: {
street: {
bsonType: 'string',
description: 'must be a string if the field exists',
},
city: {
bsonType: 'string',
description: 'must be a string and is required',
},
},
},
},
},
},
})
其它查询表达式
除了使用 $jsonSchema
(opens new window)查询运算符的 JSON Schema 校验外,MongoDB 还支持其它查询运算符的校验,但以下情况除外:
【示例】查询表达式中指定校验规则
db.createCollection('contacts', {
validator: {
$or: [
{ phone: { $type: 'string' } },
{ email: { $regex: /@mongodb\.com$/ } },
{ status: { $in: ['Unknown', 'Incomplete'] } },
],
},
})
行为
校验发生在更新和插入期间。添加校验规则到 collection 时,不会对现有的 document 进行校验,除非发生修改操作。
现有的 document
validationLevel
选项确定 MongoDB 进行规则校验时执行的操作:
- 如果
validationLevel
是 strict(严格级别。这是 MongoDB 默认级别),则 MongoDB 将校验规则应用于所有插入和更新。 - 如果
validationLevel
是 moderate(中等级别),则 MongoDB 只对已满足校验条件的现有文档的插入和更新操作进行校验;对不符合校验标准的现有文档的更新操作不进行校验。
下面是一个正常的插入操作:
db.contacts.insert([
{
_id: 1,
name: 'Anne',
phone: '+1 555 123 456',
city: 'London',
status: 'Complete',
},
{ _id: 2, name: 'Ivan', city: 'Vancouver' },
])
在 collection 上配置一个校验规则:
db.runCommand({
collMod: 'contacts',
validator: {
$jsonSchema: {
bsonType: 'object',
required: ['phone', 'name'],
properties: {
phone: {
bsonType: 'string',
description: 'must be a string and is required',
},
name: {
bsonType: 'string',
description: 'must be a string and is required',
},
},
},
},
validationLevel: 'moderate',
})
则 contacts
collection 现在添加了含中等级别(moderate) validationLevel 的 validator
:
- 如果尝试更新
_id
为 1 的文档,则 MongoDB 将应用校验规则,因为现有文档符合条件。 - 相反,MongoDB 不会将校验
_id
为 2 的文档,因为它不符合校验规则。
如果要完全禁用校验,可以将 validationLevel
置为 off
。
接受或拒绝无效的 document
- 如果 validationAction 是 Error(默认),则 MongoDB 拒绝任何违反校验规则的插入或更新。
- 如果 validationAction 是 Warn,MongoDB 会记录所有的违规,但允许进行插入或更新。
创建集合时,配置 validationAction
为 warn。
db.createCollection('contacts2', {
validator: {
$jsonSchema: {
bsonType: 'object',
required: ['phone'],
properties: {
phone: {
bsonType: 'string',
description: 'must be a string and is required',
},
email: {
bsonType: 'string',
pattern: '@mongodb.com$',
description:
'must be a string and match the regular expression pattern',
},
status: {
enum: ['Unknown', 'Incomplete'],
description: 'can only be one of the enum values',
},
},
},
},
validationAction: 'warn',
})
尝试插入一条违规记录
> db.contacts2.insert( { name: "Amanda", status: "Updated" } )
WriteResult({ "nInserted" : 1 })
MongoDB 允许这条操作执行,但是服务器会记录下告警信息。
{"t":{"$date":"2020-09-11T16:35:57.754+08:00"},"s":"W", "c":"STORAGE", "id":20294, "ctx":"conn14","msg":"Document would fail validation","attr":{"namespace":"test.contacts2","document":{"_id":{"$oid":"5f5b36ed8ea53d62a0b51c4e"},"name":"Amanda","status":"Updated"}}}
限制
不能在 admin
、local
、config
这几个特殊的数据库中指定校验规则。不能在 system.*
collection 中指定校验。