Generating MongoDB Validation Rules From a Design

For a backend developer who keeps a MongoDB design on a diagram and wants the collection validators generated from it instead of typed by hand.

On this page

The shape of a MongoDB collection lives in three places at once: in the documents already stored, in the application code that writes them, and in whatever diagram the team drew last. Only one of the three is enforced, and it is none of those: the validation rule on the collection. DbSchema closes that gap by generating the rule from the design, so the diagram you review and the structure the database enforces are the same document.

How does MongoDB handle relationships between data in collections?

MongoDB gives you two ways to relate data: embedding a related document inside its parent, and referencing it from another collection by identifier. Embedding stores the related data in the same BSON document; referencing keeps it separate and links the two with an ObjectId.

Embedded documents and arrays suit a one-to-few relationship whose children are always read with the parent, because a single read returns the whole object graph and no second lookup is needed.

The limits decide the rest. One BSON document may not exceed 16 mebibytes, and a document may not nest more than 100 levels deep, where every object and every array adds a level[1]. An array that gains an entry on every login or every order eventually breaks the write that appends to it, which is why an unbounded child list belongs in its own collection.

Embedding compared with referencing

RelationshipWhere the child goesRead patternWhat enforces the structure
One to fewEmbedded documentOne readThe parent's validation rule
One to manyReferenced ObjectIdSecond query or $lookupThe child's own validation rule
One to very manyReferenced parent idIndexed child lookupsThe child's own validation rule

Referencing stores an ObjectId in one document that points at a document in another collection. MongoDB does not check that the target exists, does not cascade a delete along it, and declares no constraint you could read back later.

How to connect two collections in MongoDB?

Two collections are connected either by storing an identifier in one of them, or by joining them at query time with the $lookup aggregation stage. Neither creates a foreign key: MongoDB has no database-level constraint that would keep the reference valid.

The DbSchema Relational Data Editor over a MongoDB tasks collection, offering cascades to the projects and users collections through two virtual relations

DbSchema closes that gap on the design side with virtual relations, which are links MongoDB neither declares nor enforces. You create one by dragging a field of the child collection onto the field it points at in the parent, DbSchema draws the connector line between the two collections, and the definition is saved in the model file. The database is not modified.

Browsing several collections over the virtual relations

The Relational Data Editor uses those relations to open several collections side by side. Selecting a document in the parent pane refilters the child panes to the documents whose field values match, and the cascade goes as many levels deep as the relations do. The data browse is a Pro edition feature; the diagram and the sampling that feed it are in the free Community Edition.

  1. Drag the reference field of a child collection onto the _id field of its parent.
  2. Check the connector line DbSchema drew between the two collections on the diagram.
  3. Save the model, which is where the relation is stored.
  4. Open the Relational Data Editor and select a parent document to see its children filtered beside it.

Is MongoDB still relevant in 2026?

MongoDB earns its place wherever the record you store differs from one instance to the next: a product catalogue whose attributes depend on the category, an event log whose payload changes with the event type, a user profile that gains a field with every release. A relational table would need a column that most rows leave null, or a join, for each of those.

What changed since the early days is that the flexibility is no longer all-or-nothing. You choose per collection where the structure is fixed and where it stays open: a payments collection gets a strict validator on the fields the accounting code depends on, while the metadata subdocument next to it stays free-form. Where a service writes a field the consumers do not expect, the validator on the collection is what rejects the write instead of a deserialization error in the consumer weeks later. If you want the rule syntax itself, the validator document, bsonType, required and a worked shell example, MongoDB validation rules explained with examples covers that ground; this article is about producing the same rule from a design.

Does MongoDB use collections?

MongoDB stores documents in collections rather than in tables. A collection is a namespace holding BSON documents that need not share a field list or field types, and it is the unit MongoDB uses for indexes, for access control and as the starting point of an aggregation pipeline.

The DbSchema collection editor for a MongoDB users collection, with the field types read from sampled documents and the structure marked as inferred, with no validation behind it

Understanding an existing MongoDB database therefore means reading real documents, because nothing else describes their shape. DbSchema introspects a configurable sample of documents per collection instead of scanning all of them, and infers the field names, the BSON types, the nested sub-documents and the arrays it finds in the sample.

What comes out is an approximation of what the database currently holds, not a contract it enforces, and DbSchema says so: a reverse-engineered collection that carries no validator of its own is marked on screen as inferred, with no validation behind it, and a document that omits a field the sample suggested was mandatory still inserts. Sampling has a second blind spot. Where the sampled documents disagree about a field's type, a string in some and an array in others, the diagram shows one type and does not flag the collision. A validation rule removes both blind spots, which is the argument for generating one.

These MongoDB database diagrams are what you read to find the nested hierarchies, the undocumented attributes and the collections nobody has touched in a year.

Who is MongoDB's biggest competitor?

Amazon DocumentDB is the managed document database that answers the same requirements, and it is MongoDB-compatible rather than MongoDB: AWS documents compatibility with the MongoDB 3.6, 4.0, 5.0 and 8.0 APIs[2]. Azure Cosmos DB competes with a multi-model service, and PostgreSQL takes the other route, keeping documents in a JSONB column inside a relational table.

Compatibility is not equality, and the differences AWS lists are the ones that reach application code:

BehaviorMongoDBAmazon DocumentDB
Retryable writesEnabled by default from the 4.2 driversNot supported, disable them in the connection string
Implicit result orderOrdering is not guaranteed without a sortOrdering is not guaranteed without a sort
$lookup subqueriesCorrelated and uncorrelatedUncorrelated only
$natural sortingForward and reverseForward scans only

Every one of those differences is documented by AWS on the same page[2], together with two more that surface during operations: Amazon DocumentDB allows only one index build per collection at a time, so a createIndex issued while another build runs fails, and it runs a different engine underneath, so the query plans that explain() prints differ from MongoDB's. Because DbSchema models document collections and relational tables in the same project, a MongoDB design and the PostgreSQL schema next to it are two diagrams in one model file rather than two tools.

Generating the validator from the design

Writing a JSON Schema validator by hand is where the design usually stops. The document is long, it is nested, and a reviewer cannot see from the diff whether it matches the diagram the team agreed on last week.

The validator script DbSchema generated from a MongoDB model, a db.createCollection call whose validator block lists the required fields and a bsonType per field

DbSchema generates the validation rule from the collection you drew. MongoDB stores such a rule as a validator on the collection, most often a $jsonSchema[3] document listing the required fields and a bsonType for each. You define those fields, their BSON types and which of them are mandatory on the diagram, and the model emits exactly that db.createCollection call, followed by a collMod[4] command that sets validationLevel and validationAction.

From there the rule goes one of two ways, and the difference is worth being deliberate about. DbSchema applies the validators to the connected database for you, which changes the live collections; or it writes the script to a file, which changes nothing until you have read it, committed it and run it yourself. Creating or editing a collection in DbSchema writes the validation rule to both the database and the local model file. Drawing a virtual relation or moving a collection on the canvas changes the model file alone. One detail to know before you run an exported script somewhere else: it opens with a CREATE DATABASE statement, which DbSchema's own Query Editor understands and mongosh does not.

Where an existing collection already carries a validation rule, DbSchema reverse-engineers that rule as the authoritative structure instead of the sampled approximation, so a round trip through the design does not weaken what the database already enforces. Fields, BSON types and mandatory flags are what the diagram carries; a constraint such as minimum or pattern, and a rule nested several documents deep, is typed into the validator itself and travels with the rest of the collection.

What to check afterwards

MongoDB schema validation[5] runs on inserts and updates, never on the documents already stored, so a rule applied to a populated collection needs four checks before you trust it.

  1. Insert a document with a wrong type through db.collection.insertOne() and confirm the database rejects it.
  2. Read back validationLevel and decide between strict and moderate for the migration you are in the middle of.
  3. Read back validationAction, error for enforcement and warn while you are still cleaning up.
  4. Query db.getCollectionInfos({ name: 'yourCollection' }) and compare the validator it returns with the one you designed.

Then hand the design to the people who do not have DbSchema open. Exporting the model as interactive HTML5 database documentation produces a vector diagram in which the collection and field comments are readable as mouse-over tooltips, which is the form a reviewer or a new colleague can use without installing anything. That export is a Pro edition feature.

Keep the exported validation script and the model file in version control next to the application code. The rule that governs a collection then has a history: a reviewer sees the validator change in the same pull request as the code that depends on it, and you can tell which release tightened which field.

Connect DbSchema to your MongoDB deployment, let it sample the collections and read the diagram it draws. Connecting, reverse-engineering, the interactive diagrams and the SQL editor are in the free Community Edition, which covers every supported database; saving the model to a file, designing against it offline and the Relational Data Editor are Pro, and the 15-day trial covers them. Download DbSchema at https://dbschema.com/download.html, open a model against your own database, and generate the validation rules from a design you can see.

Frequently asked questions

What is a MongoDB validation rule?

A validation rule is a JSON Schema document stored on the collection under its validator key, as $jsonSchema. It names the fields a document must carry and the BSON type each one may hold. With no settings of your own it applies to every insert and update and rejects what breaks it, because validationLevel defaults to strict and validationAction to error.

What happens if a collection already has validation rules?

The rule already on the collection is what DbSchema starts from, rather than a guess from a sample. The section Generating the validator from the design above covers what a round trip through the design does to a rule that is already in place.

Can MongoDB enforce foreign keys between collections?

MongoDB declares no foreign keys and enforces none, and the validator this article generates covers one collection's own fields. The section How to connect two collections in MongoDB? above covers what DbSchema records in place of a constraint.

Sources

  1. mongodb.com
  2. Functional differences: Amazon DocumentDB and MongoDB
  3. Specify JSON Schema Validation, MongoDB Manual
  4. collMod, MongoDB Manual
  5. Schema Validation, MongoDB Manual

Generate MongoDB validation rules from a design you can see

DbSchema samples your collections, draws them as a diagram, and turns the design into a $jsonSchema validator you can apply or export. Connecting, reverse-engineering and diagrams are in the free Community Edition.