MongoDB集合验证规则失效问题求助
Hey there! Let’s figure out this wonky MongoDB validation behavior you’re dealing with. I’ve run into similar head-scratchers before, so let’s break it down together.
From what you’ve described:
- You can’t insert docs with a
birthdatethat fails your regex (that’s expected, but the abnormal part is you can insert some docs that should be blocked, right?) - You’ve tried two validation approaches: query operators (swapped
$or/$and) and$jsonSchema, but both are acting weird.
Let’s dig into each method’s common pitfalls.
MongoDB’s query-based validation works like this: If the validator returns true for a document, it’s allowed; false blocks it. This is easy to mix up, so let’s check the most common mistakes:
Common Mistake 1: Reversed Logic
Suppose your validator looks like this (trying to block bad birthdate values):
{ validator: { birthdate: { $not: { $regex: /^\d{4}-\d{2}-\d{2}$/ } } }, validationLevel: "strict", validationAction: "error" }
This would allow docs with invalid birthdate (since the validator returns true for them) and block valid ones. Oops—total reverse of what you want.
Common Mistake 2: Misconfigured validationLevel
validationLevel: "strict": Validates all docs, even those without thebirthdatefield.validationLevel: "moderate": Only validates docs that include thebirthdatefield (skips docs where it’s missing).
If you wanted birthdate to be optional (allowed to be missing), but your validator uses $and to check existence + regex, strict mode would block docs without birthdate (since the validator returns false). But moderate would let them through—maybe that’s the "allowed document" you’re seeing?
Fix for Query Operator Validation
If your rule is: birthdate is optional, but if present, must match the regex:
db.createCollection("your-collection", { validator: { $or: [ { birthdate: { $exists: false } }, // Allow missing birthdate { birthdate: { $regex: /^\d{4}-\d{2}-\d{2}$/ } } // Allow valid format ] }, validationLevel: "strict", validationAction: "error" })
If birthdate is required, swap to $and:
validator: { $and: [ { birthdate: { $exists: true } }, { birthdate: { $regex: /^\d{4}-\d{2}-\d{2}$/ } } ] }
$jsonSchema Validation JSON Schema validation is stricter, but it has its own gotchas:
Common Mistake 1: Unescaped Regex Patterns
In JSON, backslashes need to be escaped. If you wrote your pattern as "^\d{4}-\d{2}-\d{2}$", that’s invalid—MongoDB won’t parse the regex correctly. You need double backslashes:
pattern: "^\\d{4}-\\d{2}-\\d{2}$"
Common Mistake 2: Missing required Field (or Overly Permissive Schema)
If your schema doesn’t list birthdate in the required array, docs without birthdate will be allowed. If you do require it, make sure to add it:
$jsonSchema: { bsonType: "object", required: ["birthdate"], // Enforce birthdate exists properties: { birthdate: { bsonType: "string", pattern: "^\\d{4}-\\d{2}-\\d{2}$" } }, additionalProperties: true // Allow other fields (default is true) }
Common Mistake 3: Wrong bsonType
If you’re inserting birthdate as a Date object instead of a string, the schema’s bsonType: "string" will reject it—even if the date format is correct. Double-check your input data type!
- Verify
validationActionis set to"error"(not"warn"—warnonly logs a message but lets the doc pass). - If you modified the validation rule after creating the collection, use
collModto update it (just overwriting won’t work):db.runCommand({ collMod: "your-collection", validator: { /* updated rule */ }, validationLevel: "strict", validationAction: "error" }) - Test edge cases: Insert a doc with no
birthdate, a doc with a valid string, a doc with an invalid string, and a doc with aDatetype—see which ones pass/fail to narrow down the issue.
内容的提问来源于stack exchange,提问作者Takezoshi

