See it as a diagram
Everything below, as a diagram you can edit. Describe yours and see it in seconds.
No account needed · Editable canvas, not a picture
Sampling is the schema
The inference pipeline is short enough to memorize: $sample pulls a random set of documents, $objectToArray turns each document into an array of key-value pairs, $unwind flattens them, and a $group counts how often each field appears and which BSON types it takes. Run per collection, the output is a field list with presence percentages and observed types, which is exactly the node content of the diagram.
The presence percentage matters more than it would in a relational schema. A field in 100 percent of sampled documents is structure; a field in 40 percent is a variant your diagram should show as optional; two disjoint field sets in one collection usually mean two document types sharing a namespace, worth splitting into separate nodes.
db.orders.aggregate([
{ $sample: { size: 1000 } },
{ $project: { kv: { $objectToArray: "$$ROOT" } } },
{ $unwind: "$kv" },
{ $group: {
_id: "$kv.k",
seen: { $sum: 1 },
types: { $addToSet: { $type: "$kv.v" } }
} },
{ $sort: { seen: -1 } }
])What Compass does, and where it stops
MongoDB Compass ships this exact idea as the Schema tab: it analyzes a sample of the collection, roughly a thousand documents, and charts field presence and types. It is the fastest way to explore one collection interactively, and the same analysis is scriptable through the open source mongodb-schema library Compass builds on.
What Compass does not give you is the map: no cross-collection view, no relationship edges, no artifact that lives in your docs and follows changes. Treat it as the per-node microscope, and the diagram as the thing that holds the nodes together.
Relationships are conventions, not constraints
There are no foreign keys to query. A relationship in MongoDB is a habit the application keeps: a manual reference like orders.userId holding an _id from users, a $lookup stage in an aggregation joining the two at read time, or an embedded document that makes the relationship containment instead of reference. None of these are enforced or recorded by the server.
That relocates the source of truth for edges: it is the application code, not the database. The $lookup stages in your aggregations and the reference fields in your models are the edge list, and an agent reading the codebase extracts them far more reliably than any sampling of the data can. Sampling names the nodes; the code names the arrows.
Regenerate on model changes, because the database will not tell you
In Postgres the redraw hooks onto migrations. MongoDB has no equivalent event: a deploy that starts writing a new field changes the schema with no ceremony at all. The honest trigger is the model layer, where the shape is actually decided: Mongoose schemas, ODM classes, or validator definitions. A CI job filtered on the models directory reruns the inference and asks an agent connected to Datadef's MCP server, registry name io.datadef/mcp, to update the diagram, with an API key from settings, on paid plans. Datadef does not watch the cluster or the repo; the model-file change is the detection.
For the first diagram, the MongoDB diagram generator takes a description or a pasted model file and returns an editable canvas. Teams that define shape through Prisma have a stronger variant of this loop, since the schema file is explicit: see living diagrams from a Prisma schema.
If you have $jsonSchema validators, use them
The limits of sampling
Sampling has a floor: a field present in 0.1 percent of documents will usually miss a 1,000-document sample entirely, so rare variants and legacy fields escape the diagram. Raise the sample size for collections with known long tails, or $match on a discriminator field and sample each document type separately.
And the surface limits that apply everywhere: a live-embedded diagram requires the project shared public, and the loop keeps the collection map current, not the written documentation around it.
FAQ
How do I generate a schema diagram for MongoDB?
How does MongoDB Compass analyze schema, and can I script it?
How do I find relationships between MongoDB collections?
When should a MongoDB schema diagram be regenerated?
Why is a field missing from my sampled MongoDB schema?