MongoDB path · Documents and schemas · Topic 1 of 12

Documents, BSON and when they fit

Not started

A MongoDB document is a record made of field-value pairs, where a value can itself be a document or an array. Documents live in collections, and the server stores them as BSON, a binary format with more types than JSON. The model's promise is that data used together is stored together: one read fetches an order with its lines, and one atomic write changes it. The cost is that data shared between many records has to be either copied or referenced, and you decide which.

Why it matters: The document model pays off when you read and write whole aggregates. Use it for highly connected data with many-to-many relationships and ad-hoc joins, and you pay for that choice on every query.

  1. 1A document is a nested record

    Fields can hold sub-documents and arrays, so an order can carry its lines and its shipping address inside it.

  2. 2BSON has more types than JSON

    Dates, ObjectId, 32- and 64-bit integers, doubles and Decimal128 are distinct types, and the type you store decides how values compare and sort.

  3. 3One document, one atomic write

    A write to a single document is atomic, however many fields and array elements it changes. Data you always change together belongs in one document.

  4. 4Flexible is not schemaless

    The server does not force one shape per collection, but your code still expects one. Without validation, nothing stops a typo from becoming a new field.

1

How it works

The explanation, with examples you can run.

What a document looks like

db.orders.insertOne({  _id: "o-1001",  customerId: 42,  status: "pending",  createdAt: new Date("2026-10-16T09:30:00Z"),  totalCents: 2500,  shipTo: { city: "Leeds", postcode: "LS1 4AP" },  items: [    { sku: "sku-7", qty: 2, priceCents: 750 },    { sku: "sku-19", qty: 1, priceCents: 1000 }  ]})

Every document needs a unique _id, and the collection always has an index on it. If you do not supply one, the driver generates an ObjectId: 12 bytes made of a 4-byte timestamp in seconds, a 5-byte random value per process and a 3-byte counter. ObjectIds therefore sort roughly by creation time, which is handy, and become a problem in the sharding topic.

Types matter

BSON distinguishes 32-bit int, 64-bit long, double and decimal, and mongosh picks for you. Checking with $type on the server:

db.t.insertOne({ _id: 1, a: 42, b: 4.5, c: 3000000000, d: NumberDecimal("19.99"), e: new Date(0) })db.t.aggregate([{ $project: { _id: 0, a: { $type: "$a" }, b: { $type: "$b" },  c: { $type: "$c" }, d: { $type: "$d" }, e: { $type: "$e" } } }])
[ { "a": "int", "b": "double", "c": "double", "d": "decimal", "e": "date" } ]

3000000000 silently became a double. Values of different numeric types still compare by value, but store dates as dates rather than strings, money as integer cents or Decimal128, and be consistent: an index on a field holding a mix of strings and numbers sorts them into separate groups.

When it fits, and when it does not

Fits wellFits poorly
Aggregates read and written as a unit (orders with lines, user profiles, content items)Many-to-many data joined in different directions for ad-hoc reports
Varying attributes per record (catalogues, settings, event payloads)Strict invariants spanning many records (double-entry ledgers)
Read-heavy pages that want one round tripData that is mostly shared and referenced, rarely owned

None of these are absolute. MongoDB has $lookup for joins, multi-document transactions and schema validation, and PostgreSQL has jsonb columns. The question is which operations are common and cheap in your workload. A document database rewards designing around the queries you run (the next topic); a relational database rewards designing around the entities and letting the planner find a way to answer any question.

2

Check yourself

3 questions. Get them all right to finish this topic.

  1. 1.In mongosh you insert { qty: 3000000000 }. What BSON type does the server store for qty?
  2. 2.Which workload suits the document model best?
  3. 3.An order and its lines live in one document. Two clients each add a line at the same moment with $push. What happens?

0 of 3 right so far. Get all three to finish this topic.