How it works
The explanation, with examples you can run.
A validator
db.createCollection("customers", { validator: { $jsonSchema: { bsonType: "object", required: ["email", "plan"], properties: { email: { bsonType: "string", pattern: "^.+@.+$" }, plan: { enum: ["free", "pro"] } } } }, validationLevel: "strict", validationAction: "error"}) db.customers.insertOne({ email: "ana@example.com", plan: "gold" })The insert fails with code 121, "Document failed validation", and the error's errInfo says exactly why:
{ "operatorName": "properties", "propertiesNotSatisfied": [{ "propertyName": "plan", "details": [{ "operatorName": "enum", "specifiedAs": { "enum": ["free", "pro"] }, "reason": "value was not found in enum", "consideredValue": "gold" }] }]}(Trimmed from errInfo.details.schemaRulesNotSatisfied.) Log or return those details; "Document failed validation" alone sends people hunting.
By default extra fields are allowed. Add additionalProperties: false to forbid them, but then you must list _id too.
Levels and actions
validationLevel decides which writes are checked:
strict(the default) checks every insert and every update.moderatechecks inserts and updates to documents that are already valid, and lets updates to existing invalid documents through.constraint(new in MongoDB 9.0) also guarantees that every document already in the collection is valid.
validationAction decides what happens to a failing write: error (the default) rejects it, warn accepts it and writes the violation to the server log, and errorAndLog (new in 8.1) rejects it and logs it.
Rolling out a validator
Adding one to a live collection does not touch existing documents. A careful sequence:
- Find violators first:
db.customers.find({ $nor: [ { $jsonSchema: schema } ] }), with the same schema object, lists documents that do not match. - Apply the validator with
collModandvalidationAction: "warn", and watch the log for writers you did not know about. - Fix the data and the writers, then switch to
error.
db.runCommand({ collMod: "customers", validator: { $jsonSchema: { /* ... */ } }, validationAction: "warn" })A validator checks one document at a time. It cannot check that a customerId exists in another collection or that a value is unique (that is a unique index's job).
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.