What kinds of rules can a MongoDB $jsonSchema validator not enforce?
answer
- think about what the validator can see
- one document, at write time
- uniqueness needs something that scans other documents
- it can only say yes or no
- a privileged write can skip it
basics
~20 sA validator sees only the single document being written, so it cannot enforce uniqueness, cross-collection references, or anything about other documents. It also never supplies defaults or coerces types, and privileged writes can bypass it entirely.
solid answer
~50 sThe validator's world is one document at write time. That rules out three families of constraint. **Cross-document** rules — "this email is unique", "at most one active subscription per customer" — belong to a unique or partial unique index, not a validator. **Cross-collection** rules — referential integrity between an order and a customer — have no server-side mechanism at all; they live in application code or a multi-document transaction. **Anything requiring mutation** is out too: `$jsonSchema` does not support the JSON Schema `default` keyword, so a validator never fills in a missing field and never coerces `"12.50"` into a number; it only accepts or rejects. There are mechanical limits as well — `$near`, `$nearSphere`, `$text` and `$where` are not allowed inside a validator expression — and a validator can be skipped by a privileged write using `bypassDocumentValidation`, which restore and import tooling commonly does.
code
javascript · 8 lines// cross-field rule inside one document: $jsonSchema alone cannot, $expr can
db.runCommand({
collMod: "bookings",
validator: { $and: [
{ $jsonSchema: { bsonType: "object", required: ["startsAt", "endsAt"] } },
{ $expr: { $gt: ["$endsAt", "$startsAt"] } }
] }
})go deeper
Remember the validator only looks at the one document being written, so rules about other documents — like an email being unique — are not its job.
Explain the consequences of that scope: uniqueness comes from a unique index, referential integrity has no server-side mechanism, and validators never supply defaults or coerce types.
Demonstrate the operational edges: $expr for cross-field rules inside a document, bypassDocumentValidation in restore paths, and why a validator on a collection is not evidence that its documents conform.
Own where each class of invariant lives across the system — index, validator, application, transaction — and how that allocation is reviewed so nobody assumes a guarantee the database was never making.
## The scope of a validator is exactly one document When MongoDB evaluates a collection validator, the input is the single document the write would leave behind. Not the previous version of that document, not any other document, not any other collection. Almost every real limitation follows from that one sentence. ## Cross-document rules: use an index "No two users share an email address" cannot be a validator, because judging it requires looking at every other document. The mechanism that does enforce it is a unique index: ```js db.users.createIndex({ email: 1 }, { unique: true }) ``` A conditional version of the same rule — "at most one *active* subscription per customer" — is a partial unique index, where `partialFilterExpression` restricts which documents the uniqueness applies to. Candidates often reach for the `uniqueItems` keyword here; that is a genuine `$jsonSchema` keyword, but it constrains elements *within one array in one document*, which is a different rule entirely. ## Cross-collection rules: there is no foreign key MongoDB has no referential-integrity constraint. A validator on `orders` cannot check that `customerId` names a document that exists in `customers`, because it cannot read `customers`. The available answers are: embed the data so the question does not arise, check the reference in application code, or perform both writes inside a multi-document transaction so the pair succeeds or fails together. None of these is a server-enforced constraint in the relational sense, and a design that quietly depends on one is a design that will accumulate dangling references. ## No defaults, no coercion, no repair MongoDB's `$jsonSchema` implementation omits several standard JSON Schema keywords, `default` and `$ref` among them. Even if `default` were accepted, it would not fit: a validator is an accept/reject predicate, not a transformation. It will never populate a missing `createdAt`, never turn a string into a `Decimal128`, never trim whitespace. Defaults belong in the application layer or in the shape of the update you send. This surprises people arriving from ORM-backed relational schemas, where `DEFAULT` clauses and type coercion are part of the same declaration. ## Operators you cannot use inside a validator A validator may be any query expression, not only `$jsonSchema` — `{ qty: { $gt: 0 } }` is a perfectly good validator — but four operators are disallowed inside one: `$near`, `$nearSphere`, `$text` and `$where`. The geospatial and text ones need indexes to evaluate; `$where` executes JavaScript and is excluded from the write path deliberately. ## What you *can* do that pure JSON Schema cannot One intra-document limitation has a workaround worth knowing: `$jsonSchema` describes each field in isolation and cannot compare two fields of the same document. But since the validator is a query expression, you can combine `$jsonSchema` with `$expr` under `$and`, and `$expr` can compare field values: ```js validator: { $and: [ { $jsonSchema: { bsonType: "object", required: ["startsAt", "endsAt"] } }, { $expr: { $gt: ["$endsAt", "$startsAt"] } } ] } ``` That stays inside the one-document rule, so it is legal — and it is the standard answer to "can a validator enforce that the end is after the start?" ## It is a guardrail, not a law Three further caveats separate a validator from an unbreakable invariant: - **`bypassDocumentValidation: true`** on a write skips the check. It requires a specific privilege, but that privilege comes bundled with roles used by restore and bulk-import tooling. Restoring an old backup can reintroduce shapes the validator would refuse. - **Existing documents are never checked.** Validation is a write-path mechanism, and under `validationLevel: "moderate"` even updates to already-failing documents are exempt. "This collection has a validator" is not the same claim as "every document in this collection conforms" — if you need the second, query for it with `$nor` and `$jsonSchema`. - **Placement restrictions.** You cannot attach a validator to collections in the `admin`, `local` or `config` databases, nor to `system.*` collections. ## How to answer this in an interview Lead with the scope sentence — one document, at write time — and derive the rest from it: uniqueness is an index's job, referential integrity is nobody's job server-side, and defaults and coercion are the application's job. Then add the two things that catch people out: `$expr` extends a validator to cross-field rules within the same document, and `bypassDocumentValidation` means a validator constrains your application rather than guaranteeing your data.
- How would you enforce that endsAt is always later than startsAt in the same document?Not with $jsonSchema alone — it constrains each field in isolation. Because a validator can be any query expression, combine them: `{ $and: [ { $jsonSchema: ... }, { $expr: { $gt: ["$endsAt", "$startsAt"] } } ] }`. $expr compares field values within the document being written, which stays inside the validator's single-document scope.
- A team says the validator guarantees every document in the collection matches the schema. Why is that claim wrong?Validation runs on writes only. Documents stored before the validator existed are never rescanned; under validationLevel moderate, updates to already-failing documents are exempt too; and privileged writes can pass bypassDocumentValidation. To claim conformance you have to prove it by querying: countDocuments({ $nor: [ { $jsonSchema: S } ] }) must be zero.
- Which mechanism enforces 'at most one active subscription per customer'?A partial unique index — a unique index whose partialFilterExpression restricts it to documents where the subscription is active. A validator cannot express it because judging it requires reading other documents, which is outside a validator's single-document scope.
saying these in an interview costs you the question
- Claims a validator can enforce uniqueness across documents
- Uses uniqueItems for cross-document uniqueness rather than within one array
- Expects the validator to apply default values or convert types
- Treats a validator as unbypassable rather than a guardrail on application writes
- Assumes a validator implies every stored document already conforms