公告介绍MongoDB 8.0,史上最快的MongoDB!阅读更多 >>介绍MongoDB 8.0,史上最快的MongoDB!>>

JSON Schema 示例教程

要跟随着本教程,您需要 MongoDB Atlas 账户并下载 MongoDB Compass。

JSON(JavaScript 对象表示法)是一种简单轻量级的基于文本的数据格式。JSON Schema 是一个 IETF 标准,提供了关于特定应用所需的 JSON 数据格式及其交互方式的格式。在 JSON 文档中应用此类标准可以帮助您确保类似 JSON 数据的一致性和数据有效性。

让我们看看一个包含人名及其室内和室外爱好文档的示例。

{
  "id": 7,
  "name": "John Doe",
  "age": 22,
  "hobbies": {
        "indoor": [
            "Chess"
        ],
        "outdoor": [
            "BasketballStand-up Comedy"
        ]
    }
}

如果您查看上述示例,您不一定知道 id 是否可以为零(0)。您也不知道是否可以留空 age。因此,我们需要具有关于有效数据类型和键的描述信息的元数据。此外,JSON Schema 还提供了结构化元数据的标准方式。

基本 JSON Schema 示例

让我们看一下上述文档类型的 JSON Schema 示例。

{
    "$schema": "https://json-schema.fullstack.org.cn/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "number"
        },
        "name": {
            "description": "Full name of the employee",
            "type": "string"
        },
        "age": {
            "description": "Age of the employee",
            "type": "number"
        },
        "hobbies": {
            "description": "Hobbies of the employee",
            "type": "object",
            "properties": {
                "indoor": {
                    "type": "array",
                    "items": {
                        "description": "List of indoor hobbies",
                        "type": "string"
                    }
                },
                "outdoor": {
                    "type": "array",
                    "items": {
                        "description": "List of outdoor hobbies",
                        "type": "string"
                    }
                }
            }
        }
    }
}

乍一看可能有些令人畏惧,但我们将逐步分析以深入了解。

JSON Schema 关键词和属性

在上面的示例中,我们使用了不同的关键词。以下列表解释了这些关键词的含义。

  • $schema: 表示此架构符合 IETF 标准的 v4 版本
  • $id: 定义用于解析架构内其他 URI 引用的基本 URI。
  • title: 描述架构的意图。
  • description: 给出架构的描述。
  • type: 定义数据类型。
  • properties: 定义 JSON 文档中的各种键及其值类型。
  • minimum: 定义数值数据类型的最低可接受值。
  • items: 列出可以出现在数组中的项目定义。
  • minItems: 定义数组中应出现的最小项目数。
  • uniqueItems: 强制数组中的每个项目相对于彼此是唯一的。
  • required: 列出必需的键。

有关关键词的完整列表,请访问 json-schema.org。该链接解释了您可以在架构中使用的关键词及其目的。

如何创建 JSON schema?

如果您有一个简单的 JSON 文档,可以使用在线 JSON 架构生成器,然后根据项目需求修改架构。或者,您可以按照以下步骤从头开始构建自己的 JSON schema:

开始架构

如果您已经熟悉了JSON模式的关键字和属性,我们可以直接开始创建一个基本的JSON模式。让我们从定义员工所需的五个基本关键字开始。

基本模式

{
  "$schema": "https://json-schema.fullstack.org.cn/draft/2020-12/schema",
  "$id": "https://example.com/product.schema.json",
  "title": "Record of Employee",
  "description": "This document records the details of an employee",
  "type": "object"
}

在上面的例子中,$schema链接到标识方言和为该方言编写的有效模式的资源。

$id关键字标识模式资源。关于这个关键字,这里有几个要点需要了解

  • 这个关键字中的URI是一个标识符,而不一定是网络定位符。
  • 它必须是一个字符串。
  • 它必须代表一个有效的URI引用,该引用已标准化,并解析绝对URI。
  • 它不得包含非空片段。
  • 它不应包含空片段。

title关键字给出模式的一个简短描述,您可以使用description关键字来更详细地解释模式。在上面的例子中,标题暗示这个模式是关于员工记录的,而描述详细说明了这一点。

type关键字说明了记录的有效数据类型。在上面的例子中,type设置了此文档的约束,并告诉我们这个记录是一个对象。

JSON模式属性

条目模式

上述部分中使用的模式是一个基本框架。让我们在此基础上添加一个id字段到员工记录中。

{
    "$schema": "https://json-schema.fullstack.org.cn/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "number"
        }
    }
}

我们添加了两个子属性,“id.description”,表示它是一个唯一标识符,以及“id.type”,解释说它是一个数字。

让我们对名称和年龄做同样的处理--但这次使用新的关键字。

{
    "$schema": "https://json-schema.fullstack.org.cn/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "string"
        },
        "name": {
            "description": "full name of the employee",
            "type": "string"
            "minLength":2
        },
        "age": {
            "description": "age of the employee",
            "type": "number",
            "minimum": 16
        }
    },
    "required": [
        "id"  
        "name",
        "age"
    ]
}

name属性中,我们引入了minLength关键字,以确保属性至少有两个字符。同样,在age属性中,我们使用了minimum关键字,以确保员工的年龄每次都超过16岁。它可以是类型number或类型integer。我们还使用了required关键字来定义必填属性。现在,让我们更进一步,并在employee对象内部添加一个对象。

嵌套数据结构

要在JSON格式中的对象内部添加对象,我们使用嵌套数据结构。为嵌套对象创建子模式的工作方式与创建根对象模式非常相似。您可以使用在定义根对象时使用的所有模式关键字,除了$schema$id。它们只需在模式的开头声明即可。

事物的数组

以下示例显示了如何在对象内部创建一个数组类型的数据。在这里,我们将使用一些新的关键字,除了我们之前已经使用过的。

{
    "$schema": "https://json-schema.fullstack.org.cn/draft-04/schema#",
    "$id": "https://example.com/employee.schema.json",
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "number"
        },
        "name": {
            "description": "name of the employee",
            "type": "string",
            "minLength":2
        },
        "age": {
            "description": "age of the employee",
            "type": "number",
            "minimum": 16
        },
        "hobbies": {
            "description": "hobbies of the employee",
            "type": "object",
            "properties": {
                "indoor": {
                    "type": "array",
                    "items": {
                        "description": "List of hobbies",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                },
                "outdoor": {
                    "type": "array",
                    "items": {
                        "description": "List of hobbies",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                }
            },
            "required": [
                "indoor",
                "outdoor"
            ]
        }
    },
    "required": [
        "id",
        "name",
        "age",
        "hobbies"
    ],
 "additionalProperties": false
}

在上面的例子中,我们在“hobbies”对象中定义了两个数组字段--indooroutdoor。您可能已经注意到了items关键字。这个关键字定义了每个项目的属性。

同样,minItems定义了数组中必须存在的最小项目数,maxItems定义了数组中可以存在的最大项目数,uniqueItems唯一标识每个项目。

您还会在子对象中再次看到required关键字。就像根JSON对象中的required关键字一样,子对象中的required关键字指定了子对象中的必填属性。

最后,我们还引入了additionalProperties。在上面的示例中,它是一个布尔值,取值为false,表示我们无法使用在properties关键字下未列出的任何其他属性。

然而,additionalProperties不必一定是布尔值。它也可以是一个对象。例如,在下面的模式中,这个关键字表示我们在这个模式下使用的任何附加属性都必须是字符串类型。

"additionalProperties": { "type": "string" }

描述地理坐标

虽然上面的示例仅限于一个用例,但JSON模式有无数种用途。JSON模式可以用于验证和强制一致性的一个领域是地理坐标。由于数据性质,接受无效或不一致数据的机会很高。

在下面的示例中,我们可以看到坐标是用数值数据类型表示的。

{
  "latitude": 58.858093,
  "longitude": 22.294694
}

但我们能用的坐标值是有限的,即值不能超过90或低于负90。因此,让我们创建一个JSON模式来应对这种情况。

{
  "$id": "https://example.com/geographical-location.schema.json",
  "$schema": "https://json-schema.fullstack.org.cn/draft/2020-12/schema",
  "title": "Longitude and Latitude Values",
  "description": "A geographical coordinate.",
  "required": [ "latitude", "longitude" ],
  "type": "object",
  "properties": {
    "latitude": {
      "type": "number",
      "minimum": -90,
      "maximum": 90
    },
    "longitude": {
      "type": "number",
      "minimum": -180,
      "maximum": 180
    }
  }
}

在这里,我们可以看到我们为每个属性使用了minimummaximum关键字来限制可接受值的范围。这不仅解决了数据验证问题,还确保了错误值不会通过。

在MongoDB Atlas中使用您的模式进行验证

您可以在文档验证器中使用$jsonSchema来强制在MongoDB中执行插入和更新操作时指定的模式,包括在MongoDB Atlas中。由于MongoDB以BSON(二进制JSON)存储数据,您可以轻松地将所有数据以JSON格式存储和检索。

MongoDB还允许您强制一个模式来验证您的数据并维护数据结构。我们将使用MongoDB Atlas和MongoDB Compass来演示。

假设我们将以下文档插入名为employees的集合中,该集合位于名为mongodatabase的数据库内。

文档1

{
    "id": 7,
    "name": "John Doe",
    "age": 22,
    "hobbies": {
        "indoor": [
            "Chess"
        ],
        "outdoor": [
            "Basketball"
        ]
    }
}

文档2

{
     "id": 8,
     "name": "Jonathon Smith",
     "age": 22
}

文档3

{
    "id": 1,
    "name": "Jane Doe",
    "age": 25,
    "hobbies": {
        "indoor": [
            "Chess"
        ],
        "outdoor": [
            "Football"
        ]
    }
}

将我们的集群连接到MongoDB Compass 我们将在MongoDB Compass中强制执行上一节中的模式来验证这些文档。

首先,让我们将我们的集群与Compass连接起来。

  • 登录MongoDB Atlas并点击Clusters
  • 点击CONNECT以连接到您的集群。
  • 通过添加您的IP地址创建数据库用户并设置连接安全性。然后选择选择连接方法
  • 选择使用MongoDB Compass连接
  • 如果您还没有安装,请下载MongoDB Compass并复制连接字符串。
  • 打开MongoDB Compass并将连接字符串粘贴进去。您的连接字符串应类似于以下内容
mongodb+srv://<username>:<password>@cluster0.9ddm0.mongodb.net/test

将<username>和<password>替换为您创建的数据库用户的用户名和密码。

select mongodatabase

现在,让我们进入mongodatabase并查看employees集合内的文档。

select employees

点击验证选项卡并将以下JSON模式插入以验证我们的文档。以$jsonSchema关键字开始模式定义。由于我们不需要启动时使用$id和$schema关键字,我们将移除它们。

{
  $jsonSchema: {
    "title": "Record of employee",
    "description": "This document records the details of an employee",
    "type": "object",
    "properties": {
        "id": {
            "description": "A unique identifier for an employee",
            "type": "number"
        },
        "name": {
            "description": "name of the employee",
            "type": "string",
            "minLength":2
        },
        "age": {
            "description": "age of the employee",
            "type": "number",
            "minimum": 16
        },
        "hobbies": {
            "description": "hobbies of the employee",
            "type": "object",
            "properties": {
                "indoor": {
                    "type": "array",
                    "items": {
                        "description": "List of hobbies",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                },
                "outdoor": {
                    "type": "array",
                    "items": {
                        "description": "List of hobbies",
                        "type": "string"
                    },
                    "minItems": 1,
                    "uniqueItems": true
                }
            },
            "required": [
                "indoor",
                "outdoor"
            ]
        }
    },
    "required": [
        "id",
        "name",
        "age",
        "hobbies"
    ],
 "additionalProperties": false
}
}

如果您到目前为止都按照步骤操作,您应该会得到以下结果。样本文档验证结果

由于我们的模式要求每个文档都有hobbies字段,因此id为8的文档失败,因为它没有包含所需的字段。

您还可以通过遵循设置模式验证规则的文档来设置额外的验证规则。要匹配满足指定JSON Schema的文档,可以使用$jsonSchema运算符。有关MongoDB JSON Schema文档的详细信息,请参阅该文档。

要了解更多关于MongoDB Atlas的信息,请参阅这篇文章

下一步

到现在为止,你应该已经了解了JSON Schema,为什么它被使用,以及我们如何使用它。我们当然已经扩展了这一概念,以及如何与MongoDB一起使用它,但仍有许多内容需要介绍。

如果您想了解更多关于MongoDB中JSON Schema的信息,我们建议您查阅MongoDB的JSON Schema验证资源。如果您对一般性的JSON Schema验证感兴趣,请访问这篇文章

常见问题解答

什么是JSON Schema?

JSON Schema是一个表示一组常见JSON文档格式和结构的模型。

JSON Schema的用途是什么?

我们使用JSON Schema来强制执行JSON文档之间的一致性和数据有效性。

如何创建JSON Schema?

您可以使用在线JSON Schema生成器,或通过实现相关的模式结构、关键词和属性来自定义创建。

JSON Schema是定义JSON结构的行业标准吗?

是的。JSON Schema被认为是强制执行JSON结构有效性的标准方法。

我应该在哪里提交$ jsonSchema数据?

您可以通过shell中的命令或MongoDB Compass提交$ jsonSchema数据。提交后,MongoDB将此数据与集合的元数据一起存储。