Docs 菜单

Docs 主页开发应用程序MongoDB Manual

选择如何处理无效文档

在此页面上

  • 上下文
  • 选项 1:拒收无效文档
  • 选项 2:允许无效的文档,但将其记录在日志中
  • 了解详情

您可以指定 MongoDB 如何处理违反验证规则的文档。当操作导致文档无效时,MongoDB 可以:

  • 拒绝任何违反验证条件的插入或更新。这是默认行为。

  • 允许操作继续进行,但在 MongoDB 日志中记录违规情况。

拒绝无效的文档可以确保模式保持一致。不过,在某些情况下,您可能希望允许无效的文档,例如,包含建立模式之前的文档的数据迁移。

模式的 validationAction 选项决定 MongoDB 如何处理无效的文档:

validationAction
行为
error
默认)MongoDB 拒绝任何违反验证条件的插入或更新。
warn
MongoDB 允许操作继续进行,但在 MongoDB 日志中记录违规情况。

以下过程说明如何创建拒绝无效文档的模式验证。

1

使用具有 validationAction: "error" 的 JSON 模式验证器创建一个 contacts 集合:

db.createCollection( "contacts", {
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 end with '@mongodb.com'"
}
}
} },
validationAction: "error"
} )

error validationAction 导致 MongoDB 拒绝任何无效文档并阻止它们插入该集合。

2

尝试插入以下文档:

db.contacts.insertOne(
{ name: "Amanda", email: "amanda@xyz.com" }
)

该文档违反了验证规则,因为:

  • email 字段与正则表达式模式不匹配。email 字段必须以 @mongodb.com 结尾。

  • 缺少必填的 phone 字段。

操作失败,并出现以下错误:

MongoServerError: Document failed validation
Additional information: {
failingDocumentId: ObjectId("6377cca4aac957f2b77ea955"),
details: {
operatorName: '$jsonSchema',
schemaRulesNotSatisfied: [
{
operatorName: 'properties',
propertiesNotSatisfied: [
{
propertyName: 'email',
description: "must be a string and end with '@mongodb.com'",
details: [
{
operatorName: 'pattern',
specifiedAs: { pattern: '@mongodb\\.com$' },
reason: 'regular expression did not match',
consideredValue: 'amanda@xyz.com'
}
]
}
]
},
{
operatorName: 'required',
specifiedAs: { required: [ 'phone' ] },
missingProperties: [ 'phone' ]
}
]
}
}

以下过程说明如何创建允许无效文档但将其记录在 MongoDB 日志中的模式验证。

1

使用具有 validationAction: "warn" 的 JSON 模式验证器创建一个 contacts2 集合:

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 end with '@mongodb.com'"
}
}
} },
validationAction: "warn"
} )

warn validationAction 允许将无效文档插入该集合中。无效文档会记录在 MongoDB 日志中。

2

尝试插入以下文档:

db.contacts2.insertOne(
{ name: "Amanda", email: "amanda@xyz.com" }
)

该文档违反了验证规则,因为:

  • email 字段与正则表达式模式不匹配。email 字段必须以 @mongodb.com 结尾。

  • 缺少必填的 phone 字段。

3

要以可读格式查看 MongoDB 日志,请运行以下命令:

db.adminCommand(
{ getLog:'global'} ).log.forEach(x => { print(x) }
)

MongoDB 日志包含一个类似于以下对象的条目:

{
"t": {
"$date": "2022-11-18T13:30:43.607-05:00"
},
"s": "W",
"c": "STORAGE",
"id": 20294,
"ctx": "conn2",
"msg": "Document would fail validation",
"attr": {
"namespace": "test.contacts2",
"document": {
"_id": {
"$oid": "6377cf53d59841355cac1cd0"
},
"name": "Amanda",
"email": "amanda@xyz.com"
},
"errInfo": {
"failingDocumentId": {
"$oid": "6377cf53d59841355cac1cd0"
},
"details": {
"operatorName": "$jsonSchema",
"schemaRulesNotSatisfied": [{
"operatorName": "properties",
"propertiesNotSatisfied": [{
"propertyName": "email",
"description": "must be a string and end with '@mongodb.com'",
"details": [{
"operatorName": "pattern",
"specifiedAs": {
"pattern": "@mongodb\\.com$"
},
"reason": "regular expression did not match",
"consideredValue": "amanda@xyz.com"
}]
}]
}, {
"operatorName": "required",
"specifiedAs": {
"required": ["phone"]
},
"missingProperties": ["phone"]
}]
}
}
}
}
← 指定现有文档的验证级别