验证 MongoDB 数据

MongoDBBeginner
立即练习

介绍

在本实验中,你将学习 MongoDB 中数据验证的基础知识。数据验证是一项至关重要的功能,它通过确保集合中的所有文档都遵循特定的结构和规则,来帮助维护数据的完整性和一致性。你将学习如何创建带有验证规则的集合,通过尝试插入有效和无效数据来测试这些规则,以及修改现有集合的验证规则。在本实验结束时,你将能够直接在 MongoDB 数据库中强制执行数据质量。

创建带模式验证的集合

在第一步中,你将连接到 MongoDB 服务器并创建一个带有特定验证规则的新集合。这些规则将定义文档中字段的预期数据类型和约束。

首先,打开 MongoDB Shell (mongosh) 以与你的数据库进行交互。这个交互式 shell 是你管理 MongoDB 的主要工具。

mongosh

进入 shell 后,你将看到一个类似 test> 的提示符。这表明你已连接到默认的 test 数据库。让我们创建一个名为 dataValidationLab 的新数据库并切换到它。

use dataValidationLab

现在,让我们创建一个 users 集合。在创建集合时,我们将包含一个 validator 文档,该文档使用 $jsonSchema 来定义我们的规则。

db.createCollection("users", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "age", "email"],
      properties: {
        name: {
          bsonType: "string",
          description: "must be a string and is required"
        },
        age: {
          bsonType: "int",
          minimum: 18,
          description: "must be an integer >= 18 and is required"
        },
        email: {
          bsonType: "string",
          pattern: "^.+@.+$",
          description: "must be a valid email address and is required"
        }
      }
    }
  }
});

运行命令后,你应该会看到一个表示成功的输出:

{ "ok": 1 }

让我们分解一下验证器:

  • bsonType: "object":文档的根必须是一个对象。
  • required: ["name", "age", "email"]nameageemail 字段在每个文档中都必须存在。
  • properties:此对象定义了各个字段的规则。
    • name:必须是 string 类型。
    • age:必须是 int(整数)类型,且 minimum 值为 18。
    • email:必须是 string 类型,并且匹配正则表达式 pattern,该表达式检查基本的电子邮件格式。

你现在已经成功创建了一个带有数据验证规则的集合。在下一步中,你将测试这些规则。

通过插入文档测试验证

现在你的 users 集合已经有了验证规则,让我们来测试它们。你将尝试插入几个文档:一些违反规则的文档和一个符合规则的文档。这将帮助你理解 MongoDB 如何强制执行模式。

首先,让我们尝试插入一个 age 字段数据类型不正确的文档。我们将提供一个字符串 "25" 而不是一个整数。

db.users.insertOne({
  name: "John Doe",
  age: "25",
  email: "john.doe@example.com"
});

此操作将失败。MongoDB 将拒绝该文档并返回一个 WriteError,因为 age 字段不符合 bsonType: "int" 的要求。错误消息将包含有关验证失败的详细信息。

MongoServerError: Document failed validation

接下来,让我们尝试插入一个缺少必需字段 email 的文档。

db.users.insertOne({
  name: "Jane Doe",
  age: 30
});

这也将失败,因为 email 字段在我们的验证器中列在 required 数组中。你将收到一个类似的 WriteCommandError

最后,让我们插入一个遵循所有规则的文档。nameemail 是字符串,age 是一个大于或等于 18 的整数。

db.users.insertOne({
  name: "Alice",
  age: 28,
  email: "alice@example.com"
});

这次,命令将成功,你将看到一条确认消息,其中包含新插入文档的 _id

{
  "acknowledged": true,
  "insertedId": ObjectId("...")
}

为了确认有效文档已添加,你可以查询该集合。

db.users.find();

输出将显示成功通过验证的一个文档。

[
  {
    "_id": ObjectId("..."),
    "name": "Alice",
    "age": 28,
    "email": "alice@example.com"
  }
]

修改现有验证器

你的应用程序需求可能会随时间而变化,你可能需要更新验证规则。在这一步中,你将学习如何使用 collMod 命令修改现有集合的验证器,然后测试新规则。

假设我们要为 users 集合添加一个新的 status 字段。此字段应为字符串类型,并且只能是 "active""inactive" 这两个值之一。

我们使用 collMod(collection modify)命令来应用新的验证器。

db.runCommand({
  collMod: "users",
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "age", "email", "status"],
      properties: {
        name: {
          bsonType: "string",
          description: "must be a string and is required"
        },
        age: {
          bsonType: "int",
          minimum: 18,
          description: "must be an integer >= 18 and is required"
        },
        email: {
          bsonType: "string",
          pattern: "^.+@.+$",
          description: "must be a valid email address and is required"
        },
        status: {
          enum: ["active", "inactive"],
          description: "can only be one of the enum values and is required"
        }
      }
    }
  }
});

该命令成功后将返回 { "ok": 1 }。我们现在已更新验证器,要求 status 字段存在,并使用 enum 关键字限制其值。

现在,让我们测试新规则。尝试插入一个具有无效状态的文档。

db.users.insertOne({
  name: "Bob",
  age: 45,
  email: "bob@example.com",
  status: "pending"
});

这将失败,因为 "pending" 不在 status 字段的 enum 列表中。接下来,插入一个符合更新规则的文档。

db.users.insertOne({
  name: "Bob",
  age: 45,
  email: "bob@example.com",
  status: "active"
});

此插入将成功。要查看集合中的所有文档,请再次运行 find()

db.users.find();

你现在将看到 Alice 和 Bob 的文档。请注意,Alice 的文档是在规则更改之前插入的,不包含 status 字段。默认情况下,验证不适用于现有文档,直到它们被修改为止。

总结

在本实验中,你学习了在 MongoDB 中实现数据验证的基本技术。你首先创建了一个带有 $jsonSchema 验证器的集合,以强制执行数据类型、必需字段和值约束。然后,你通过尝试插入无效和有效的文档来测试这些规则,观察 MongoDB 如何拒绝不符合模式的数据。最后,你学习了如何使用 collMod 命令修改现有集合的验证规则,以适应新的需求。这些技能对于构建健壮的应用程序和在 MongoDB 数据库中维护高质量的数据至关重要。