集合校验器怎么用
校验器为集合加一层写入约束:建集合时提供 $jsonSchema,或用 collMod 给已有集合补上。两个开关决定行为——validationLevel 控制哪些写入被校验(strict 全部、moderate 放行历史不合规文档的更新),validationAction 控制不合规时的处理(error 拒绝、warn 只记日志)。它适合在数据库层挡住结构性脏数据,但不替代应用层校验。
基本信息
| 校验器 | $jsonSchema: { bsonType: "object", required: [...], properties: {...} } |
|---|---|
| validationLevel | strict(默认,全部写入校验)/ moderate(历史不合规文档的更新放行) |
| validationAction | error(拒绝写入)/ warn(仅记录日志) |
| 给已有集合加校验 | db.runCommand({ collMod: "orders", validator: ..., validationLevel: ... }) |
| 查看 | db.getCollectionInfos({ name: "orders" }) 里可以看到 validator |
| 生效范围 | 只对启用之后的写入生效,历史数据不受约束 |
典型使用场景
- 必填字段约束:订单缺少关键字段时直接拒绝写入
- 类型与取值范围:数值下限、字符串枚举、日期格式校验
- 灰度上线校验:先用 warn 模式观察一段时间,确认无正常写入被拦再切 error
- 存量系统加固:用 moderate 模式避免历史不合规文档的更新全部失败
- 多服务写入同一集合:把公共约束下沉到数据库层,减少各服务实现差异
为已有集合加校验
为已有集合加校验
db.runCommand({
collMod: "orders",
validator: { $jsonSchema: {
bsonType: "object",
required: ["sku", "qty", "status"],
properties: {
sku: { bsonType: "string", description: "必须是非空字符串" },
qty: { bsonType: "int", minimum: 1 },
status: { enum: ["open", "paid", "closed"] }
}
} },
validationLevel: "moderate", // 历史不合规文档的更新不会被拦
validationAction: "warn" // 先观察,确认无副作用后再改 error
})
// 确认校验器已生效
db.getCollectionInfos({ name: "orders" })[0].options.validator两种开关的组合读法
| 组合 | 行为 | 适用阶段 |
|---|---|---|
| strict + warn | 所有写入都校验,但只记日志不拒绝 | 上线初期的观察窗口 |
| strict + error | 所有写入都校验并拒绝不合规数据 | 稳定运行期的标准配置 |
| moderate + error | 历史不合规文档的更新放行,新插入仍校验 | 存量数据尚未清洗完成的过渡期 |
| moderate + warn | 仅记录日志,用于评估影响面 | 评估阶段,不产生业务影响 |
更新操作校验的是更新之后的最终文档形态:部分更新如果不满足 required 条件同样会被拒绝,写更新语句时要考虑完整结构而不是只盯改动的字段。
校验器上线前先用 warn 模式跑一个业务周期:直接切 error 可能拦住既有业务的合法写入,尤其是历史代码写入的字段类型与预期不一致时。