Validation rules
A collection validator — validator, validationLevel and validationAction —
is MongoDB's only declarative constraint. If you come from a relational
database, it is where NOT NULL and CHECK went.
Open it from a collection's context menu. TableCore reads the current validator,
can propose one from a sample, and writes it back with a single collMod.
The proposal starts from your data
The proposal is generated from the same analysis the schema explorer shows, and every row justifies itself with its own number — "present in 1,000 of 1,000 sampled documents". The same sample-provenance sentence stands above the list, in the same words.
A rule the sample cannot support is absent, not unchecked
An unticked checkbox says "we could have and chose not to". A missing row says "nothing measured this". So the generator refuses in four cases, by name:
- A path inside an array. Its frequency is counted per document, not per
element, so it does not become an
itemsrule. The dialog lists such paths rather than pretending not to have noticed them. enumonly from a list that is visibly complete — one string or boolean type, few enough distinct values, and nothing truncated. Ten values out of fifty would reject the forty the sample saw.bsonTypelists every type of a field or none. A type the generator cannot name (symbol,undefined,dbPointer) takes the whole type rule with it, because a list without it rejects documents that are legal in the sample.- No
minimum/maximumforDecimal128, because reading the formatted value back through adoublemoves the boundary.
_id is never proposed. The server requires it and enforces its uniqueness
already, so required would repeat a guarantee — and a range read from sampled
identifiers (_id between 1 and 4, from four documents) rejects every document
the collection does not have yet. If you genuinely want a rule on _id, write
it in the schema panel.
Rows generate the schema, one way
Editing the JSON Schema by hand degrades the rows to a read-only view of what was parsed out of it, and the dialog says so on screen. Two-way synchronisation between a form and a hand-edited document is how editors like this start lying.
A validator this editor did not generate — written with query operators like
{ age: { $gte: 0 } }, or using keywords outside the generator such as
pattern, anyOf or items — is shown as the server's document with no rows.
Rendering the half that happens to fit would describe the validator wrongly
exactly where it matters.
Count before you apply
Applying a strict validator to a collection that already breaks it
Every later update to an old document fails — including updates that do not touch the offending field. That is the failure mode this feature is arranged around.
Before applying, TableCore counts the documents that would violate the proposed validator and shows you the first few.
- A failed count comes back as a report with no number, never as zero, and it blocks Apply.
- With a non-zero count, the first application starts at
moderate+warn, and says in one sentence why. - The count belongs to the exact text it was taken for. Any change to the schema invalidates it.
Level and action
| Setting | In plain words | Server's word |
|---|---|---|
| Level | Check every write | strict |
| Level | Only check documents that already pass | moderate |
| Action | Reject the write | error |
| Action | Allow it and log a warning | warn |
The jargon stays visible beside the plain wording, because that is what the server's own documentation calls them.
Removing a validator
Removing is a separate, confirmed action — not "clear the form and save". It
sends collMod with an empty validator and returns the level and action to the
server's defaults. A level left at off would outlive the validator it was
chosen for.
Views and time-series collections are detected and refused with the reason, rather than being sent a command that would not have worked anyway.
Validators travel with backups
A collection's validator is carried through backup and restore, in the collection's metadata file. It was being preserved there long before this dialog existed; now you can also read it.