对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。

绕过模式验证

在某些情况下,您可能需要绕过集合的模式验证规则。例如,如果您要将可能无效的数据从备份恢复到具有验证规则的集合。在这种情况下,旧文档可能无法满足新的验证要求。

绕过模式验证是按操作进行的。如果绕过模式验证插入无效文档,今后对该无效文档的任何更新都必须满足以下任一条件:

  • 同时绕过模式验证

  • 生成有效文档

如果集合的 validationLevel 为 constraint,或者 prepareConstraintValidationLevel 为 true,MongoDB 将拒绝任何将 bypassDocumentValidation 设置为 true 的写入操作。即使文档满足验证规则,写入也会失败:

{ ok: 0, errmsg: "bypassDocumentValidation is not permitted with 'constraint' validationLevel", code: 2, codeName: "BadValue"}

如果 prepareConstraintValidationLevel 为 true,则写入会失败并显示不同的消息。该消息会命名 prepareConstraintValidationLevel 并提供清除它的命令。两种故障都使用 BadValue 错误代码。

要恢复绕过验证的能力,请使用 collMod: 更新集合

  • 如果集合的 validationLevel 为 constraint,请将其设置为 strict。

  • 如果集合的 prepareConstraintValidationLevel 为 true,请将其设置为 false。

9.0版本新增。

您可以使用以下命令和方法绕过基于每个操作的验证:

对于启用了访问控制的部署,要绕过文档验证,经过身份验证的用户必须有 bypassDocumentValidation 动作。内置角色 dbAdmin 和 restore 可执行此动作。

以下示例创建了具有模式验证功能的集合,然后绕过验证规则插入了无效文档。

1

创建 students 集合并使用 $jsonSchema 运算符设置模式验证规则:

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" } } } }} )
2

以下文档无效,因为 year 字段超出了允许的范围(2017-3017):

{ name: "Alice", year: Int32( 2016 ), major: "History", gpa: Double(3.0), address: { city: "NYC", street: "33rd Street" }}

要绕过验证规则并插入无效文档,请运行以下 insert 命令,该命令将 bypassDocumentValidation 选项设置为 true:

db.runCommand( { insert: "students", documents: [ { name: "Alice", year: Int32( 2016 ), major: "History", gpa: Double(3.0), address: { city: "NYC", street: "33rd Street" } } ], bypassDocumentValidation: true} )

要确认文档已成功插入,查询 students 集合:

db.students.find()

MongoDB 返回插入的文档:

[ { _id: ObjectId("62bcb4db3f7991ea4fc6830e"), name: 'Alice', year: 2016, major: 'History', gpa: 3, address: { city: 'NYC', street: '33rd Street' } }]