Docs 菜单
Docs 主页
/
MongoDB Manual
/ /

指定 JSON schema 验证

在此页面上

  • 兼容性
  • 上下文
  • 限制
  • 步骤
  • 更多信息
  • 了解详情

JSON Schema 是一个词汇表,可用于注释和验证 JSON 文档。您可使用 JSON Schema ,以易于用户浏览的格式为字段指定验证规则。

您可以对在以下环境中托管的部署使用 JSON Schema 验证:

  • MongoDB Atlas:用于云中 MongoDB 部署的完全托管服务

  • MongoDB Enterprise:基于订阅、自我管理的 MongoDB 版本

  • MongoDB Community:源代码可用、免费使用且可自行管理的 MongoDB 版本

MongoDB 支持 JSON 模式草案4,包括核心规范验证规范 ,但存在一些差异。有关详情,请参阅扩展省略。

有关 JSON schema 的更多信息,请参阅官方网站。

不能为以下对象指定模式验证:

  • adminlocalconfig 数据库中的集合

  • 系统集合

如果在集合上启用了客户端字段级加密可查询加密,则验证会受到以下限制:

  • 对于 CSFLE,当运行collMod 时,libmongocrypt 库会优先选择命令中指定的 JSON 加密模式。这样就可以在还没有模式的集合上设置模式。

  • 对于 Queryable Encryption,任何包含加密字段的 JSON schema 都会导致查询分析错误。

在此示例中,您将创建一个带有验证规则的 students 集合,并在尝试插入无效文档后观察结果。

1

要使用 mongosh 连接到本地 MongoDB 实例或 MongoDB Atlas 部署,请参考连接到部署通过 mongosh 连接中的步骤。

2

mongosh 中,运行以下命令以创建 students 集合,并使用 $jsonSchema 操作符设置模式验证规则:

db.createCollection("students", {
validator: {
$jsonSchema: {
bsonType: "object",
title: "Student Object Validation",
required: [ "address", "major", "name", "year" ],
properties: {
name: {
bsonType: "string",
description: "'name' must be a string and is required"
},
year: {
bsonType: "int",
minimum: 2017,
maximum: 3017,
description: "'year' must be an integer in [ 2017, 3017 ] and is required"
},
gpa: {
bsonType: [ "double" ],
description: "'gpa' must be a double if the field exists"
}
}
}
}
} )

提示

使用标题和描述字段阐明规则

当规则不明确时,您可以使用 titledescription 字段来解释验证规则。当文档验证失败时,MongoDB 会在错误输出中包含这些字段。

3

运行以下命令。插入操作失败是因为 gpa 是整数,而 validator 需要 double

db.students.insertOne( {
name: "Alice",
year: Int32( 2019 ),
major: "History",
gpa: Int32(3),
address: {
city: "NYC",
street: "33rd Street"
}
} )
MongoServerError: Document failed validation
Additional information: {
failingDocumentId: ObjectId("630d093a931191850b40d0a9"),
details: {
operatorName: '$jsonSchema',
title: 'Student Object Validation',
schemaRulesNotSatisfied: [
{
operatorName: 'properties',
propertiesNotSatisfied: [
{
propertyName: 'gpa',
description: "'gpa' must be a double if the field exists",
details: [
{
operatorName: 'bsonType',
specifiedAs: { bsonType: [ 'double' ] },
reason: 'type did not match',
consideredValue: 3,
consideredType: 'int'
}
]
}
]
}
]
}
}

提示

默认, mongosh会打印最多六层的嵌套对象。 要将所有嵌套对象打印到完整深度,请将inspectDepth设立为Infinity

config.set("inspectDepth", Infinity)
4

如果将 gpa 字段值更改为 double 类型,插入操作会成功。运行以下命令以插入有效文档:

db.students.insertOne( {
name: "Alice",
year: NumberInt(2019),
major: "History",
gpa: Double(3.0),
address: {
city: "NYC",
street: "33rd Street"
}
} )
5

要确认已成功插入文档,请运行以下命令来查询 students 集合:

db.students.find()
[
{
_id: ObjectId("62bb413014b92d148400f7a5"),
name: 'Alice',
year: 2019,
major: 'History',
gpa: 3,
address: { city: 'NYC', street: '33rd Street' }
}
]

提示

如果连接到 Atlas 部署,还可以在 Atlas 用户界面中查看和过滤文档。

您可以将 JSON 模式验证与查询运算符验证结合使用。

例如,考虑具有以下模式验证的sales 集合:

db.createCollection("sales", {
validator: {
"$and": [
// Validation with query operators
{
"$expr": {
"$lt": ["$lineItems.discountedPrice", "$lineItems.price"]
}
},
// Validation with JSON Schema
{
"$jsonSchema": {
"properties": {
"items": { "bsonType": "array" }
}
}
}
]
}
}
)

前面的验证对 sales 集合中的文档强制执行以下这些规则:

  • lineItems.discountedPrice 必须小于 lineItems.price 。该规则使用 $lt操作符指定。

  • items 字段必须是数组。该规则使用 $jsonSchema 指定。

后退

模式验证