Docs & Code Guide

MongoDB schema diagram: sample the collections, because there is no DDL to read

Every other database on this surface hands over its structure in a metadata query. MongoDB cannot, because it never collected one: each document carries its own shape, and the only schema is the one your documents happen to agree on. A MongoDB diagram is therefore inferred, by sampling documents and counting fields, and kept current by watching the layer that actually defines the shape: your application models.

7 min readFor teams who need a collection map of a MongoDB database that grew without one

See it as a diagram

Everything below, as a diagram you can edit. Describe yours and see it in seconds.

236/20003 credits left
Try:

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

Collections with validation rules carry a declared shape the server enforces on write. Where validators exist, they beat sampling as diagram input; sampling then only fills in what the validator leaves open.

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?

Infer the shape per collection with an aggregation: $sample a set of documents, $objectToArray each one, then $unwind and $group to count field presence and types. Feed the per-collection results plus the reference fields from your application models into a generator. There is no DDL to export, so inference and the model layer are the sources.

How does MongoDB Compass analyze schema, and can I script it?

The Compass Schema tab samples roughly a thousand documents from the collection and charts field presence and types. The analysis logic is available as the open source mongodb-schema library, so the same inference can run in a script or CI job without the GUI.

How do I find relationships between MongoDB collections?

Read the application, not the database. Relationships are conventions: manual reference fields holding _id values, $lookup stages in aggregation pipelines, and embedded documents for containment. The server neither enforces nor records them, so the codebase is the authoritative edge list for the diagram.

When should a MongoDB schema diagram be regenerated?

When the model layer changes, because the database emits no schema-change event. Trigger a CI job on the directory holding Mongoose schemas or ODM models, rerun the sampling, and have an MCP-connected agent update the diagram. A deploy that writes new fields without touching models is the case sampling on a schedule exists to catch.

Why is a field missing from my sampled MongoDB schema?

Sampling is probabilistic: a field appearing in very few documents will often miss the sample. Increase the $sample size, or if the collection holds several document types, $match on the type discriminator and sample each subtype separately so rare shapes are represented.