模式验证
本教程共 50 篇 · 第 47 篇 · 更新于 2026-07-30 · 约 3 分钟阅读
47. 模式验证
本节目标:会用模式验证给集合加字段规则,知道校验级别与动作的差别,避免脏数据进库。
MongoDB 默认是灵活模式(Flexible Schema),同集合文档字段可以不一样。但业务稳定后,我们往往希望守住基本结构。模式验证(Schema Validation)就是干这个的。
47.1 用 $jsonSchema 定规则
MongoDB 用 JSON Schema 来描述结构。建集合时通过 validator 传入:
// 建 users 集合并规定字段规则
test> db.createCollection("users", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["name", "email", "age"],
properties: {
name: { bsonType: "string", description: "姓名必须是字符串" },
email: { bsonType: "string", pattern: "^.+@.+$" },
age: { bsonType: "int", minimum: 0, maximum: 150 },
city: { bsonType: "string" }
}
}
}
})
这条规则要求:文档必须是对象;name、email、age 必填;age 是 0 到 150 的整数;email 要像邮箱。
Tip
bsonType用 MongoDB 的类型名,比如string、int、double、date、array、object。这是验证里最常用的一栏。
47.2 不合规则会怎样
插入一条缺 email 的文档,会被直接拒绝:
// 报错:缺少必填字段 email
test> db.users.insertOne({ name: "小明", age: 28 })
插入 age 写成字符串也会失败,因为 bsonType 限定了 int:
// 报错:age 类型不对
test> db.users.insertOne({ name: "小红", email: "h@x.com", age: "28" })
47.3 validationAction:拒绝还是告警
validationAction 决定不合格时怎么办,默认是 error(拒绝写入)。也可设成 warn,放行但记日志。
// 不合格只告警不拒绝,方便灰度过渡
test> db.createCollection("users", {
validator: { $jsonSchema: { required: ["name"], properties: { name: { bsonType: "string" } } } },
validationAction: "warn"
})
Note上线初期我常先用
warn跑一段时间,观察有多少旧数据不合规,再切到error。这能避免一把锁死写入。
47.4 validationLevel:校验哪些写入
validationLevel 控制规则作用于哪些操作:
strict(默认):所有插入和更新都校验。moderate:插入校验;更新只校验「原本就合规」的文档,放过原本就不合规的老文档。
// 只对严格模式校验,老脏数据更新时不被拦
test> db.createCollection("users", {
validator: { $jsonSchema: { required: ["name"] } },
validationLevel: "moderate"
})
Warning
moderate适合「库里已有历史脏数据、又不想改它们」的过渡期。新集合一般用默认的strict更稳妥。
47.5 用查询操作符扩展校验
除了 JSON Schema,validator 还能混用查询操作符,做更复杂的约束。
// 要求 status 必须是几个固定值之一
test> db.createCollection("orders", {
validator: {
$and: [
{ $jsonSchema: { required: ["status", "total"] } },
{ status: { $in: ["pending", "paid", "shipped", "done"] } }
]
}
})
47.6 修改已有集合的验证规则
建完也能改。用 collMod 命令调整:
// 给已有 users 集合追加校验规则
test> db.runCommand({
collMod: "users",
validator: { $jsonSchema: { required: ["name", "email"] } },
validationAction: "error"
})
47.7 小结
模式验证用 validator + $jsonSchema 定结构,validationAction 选拒绝或告警,validationLevel 选校验范围。它不强制全字段,只为关键数据兜底,是灵活模式下的安全网。