mongodb 5.0+ 启用 json schema 验证需显式配置 validator、validationlevel(推荐 strict)和 validationaction(建议先设 warn);schema 不自动映射 objectid/date,需正则或 format 校验;嵌套字段须 properties 逐层定义,数组用 items;开启后不合规写入将报错,回滚仅能通过 collmod 修改 validator 或 validationaction。

如何在 MongoDB 5.0+ 中启用 JSON Schema 验证
MongoDB 原生支持 JSON Schema 验证,但不是默认开启的——必须显式配置 validator 并设置 validationLevel 和 validationAction。不配这两项,即使写了 schema 也完全不生效。
-
validationLevel推荐设为strict(仅对新插入/更新文档校验),避免历史脏数据导致集合不可写 -
validationAction建议先用warn:校验失败只打日志,不阻断写入,方便灰度观察 - 必须通过
collMod命令或createCollection一次性声明,不能后期“补加” validator 到已有集合(除非重建)
JSON Schema 字段类型与 MongoDB 类型的对应陷阱
JSON Schema 的 string、number 等类型不会自动映射到 MongoDB 的 ObjectId、Date 或 BinData。比如写 {"type": "string"},MongoDB 会接受任意字符串,但不会拒绝一个形如 "507f1f77bcf86cd799439011" 的 ObjectId 字符串——它仍是合法 string。
- 需要 ObjectId 校验?得用
pattern+ 正则:{"pattern": "^[0-9a-fA-F]{24}$"} - 需要 Date 校验?不能只靠
"type": "string",得加"format": "date-time",且客户端写入时必须是 ISO 字符串(如"2023-10-05T12:34:56Z"),MongoDB 不会把数字时间戳(如1696509296000)自动转成 Date -
required只检查字段是否存在,不检查是否为null;要排除 null,得额外加"not": {"type": "null"}
嵌套对象和数组的验证写法差异
对 address.city 这类路径校验,不能直接在顶层 schema 写 "address.city": {"type": "string"} —— JSON Schema 不支持点号路径,必须用 properties 逐层嵌套。
- 数组元素校验用
items,不是item(常见拼写错误) - 想限制数组长度?用
minItems/maxItems,不是minLength(那是字符串用的) - 嵌套对象中字段可选但一旦出现就必须合法?外层用
"required": ["profile"],内层profile的properties里再定义其子字段规则 - 示例片段:
{ "properties": { "tags": { "type": "array", "items": { "type": "string", "maxLength": 20 } } } }
验证规则上线后的真实影响与回滚准备
开启 validationLevel: strict 后,任何不符合 schema 的写操作(包括 update 操作中未提及但被 schema 要求的字段)都会报错 Document failed validation。这不是连接或权限问题,容易误判。
- 更新操作默认只校验被修改的字段,但若 schema 定义了
required字段,而 update 没带它,仍会失败(因为 update 后文档整体不满足 required) - 聚合管道写入(如
$out)、mongorestore、甚至某些 ORM 的批量 upsert 都可能触发校验,务必提前测试 - 紧急回滚方法只有两个:
collMod把validator设为空对象,或把validationAction改成warn;没有“临时关闭”开关
最常被忽略的是:schema 本身无法约束索引字段唯一性、引用完整性或业务逻辑(比如“end_time 必须大于 start_time”),这些还得靠应用层或数据库触发器兜底。










