介绍
在本实验中,你将学习 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"]:name、age和email字段在每个文档中都必须存在。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。
最后,让我们插入一个遵循所有规则的文档。name 和 email 是字符串,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 数据库中维护高质量的数据至关重要。

