BSON Data Types (Overview)
BSON Data Types (Overview)
Level 2 — BSON Data Types & Document Structure The complete type system supported by the BSON specification inside MongoDB, defining how strings, numbers, dates, lists, and nested objects are represented and stored.
1. Prerequisites
- BSON (Binary JSON) — The parent binary serialization format.
2. Term Category
Core Concept (Type System Specification): BSON Data Types define the full set of binary-encoded types supported natively by MongoDB, expanding beyond basic JSON data types.
3. Explanation
Environment Context
- MongoDB Core (Fully enforced by the storage engine. Each value in a BSON document is prefixed by a single-byte type identifier that determines how the engine parses the following bytes).
(1) Design Motivation — "Why did we design this?"
In PostgreSQL, column data types are strictly defined inside the table schema.
If a column is declared as INT, the database guarantees that every row stores a 32-bit integer in that slot.
In MongoDB, because collections are schema-free, a single field can hold different data types in different documents (e.g., status: "active" (String) and status: 1 (Integer)).
To query and sort this data safely:
- MongoDB needs a strict internal Type System to identify what kind of value is stored in every field.
- Unlike standard JSON (which only has 6 types), the BSON type system includes 19 distinct type identifiers. This allows MongoDB to support exact financial decimals, timestamps, regular expressions, and unique ObjectIds, making it a robust database engine rather than a simple text store.
(2) The Core BSON Type List
| Type Name | BSON Alias | Description | PostgreSQL Equivalent |
|---|---|---|---|
| String | "string" | UTF-8 text string. | TEXT, VARCHAR |
| Double | "double" | 64-bit floating-point number. | DOUBLE PRECISION |
| Int32 | "int" | 32-bit signed integer. | INTEGER |
| Int64 | "long" | 64-bit signed integer. | BIGINT |
| Decimal128 | "decimal" | 128-bit decimal (exact precision). | NUMERIC, DECIMAL |
| Boolean | "bool" | true or false logic. | BOOLEAN |
| Date | "date" | Milliseconds since Unix epoch. | TIMESTAMPTZ |
| Null | "null" | Absence of value. | NULL |
| Object | "object" | Embedded subdocument. | JSONB (object keys) |
| Array | "array" | Ordered list of any types. | JSONB / Array types |
| ObjectId | "objectId" | 12-byte unique identifier. | UUID |
| Binary | "binData" | Raw byte arrays. | BYTEA |
(3) Reality Metaphor
Imagine packing a compartmentalized lunchbox:
- SQL Column: A single-ingredient jar. It is labeled "Soup" (
TEXT). You can only pour soup inside. If you drop a carrot in, it breaks. - BSON Document: A Bento Lunch Box containing multiple compartments.
- Compartment 1 holds rice (String).
- Compartment 2 holds a strawberry (Boolean).
- Compartment 3 holds 3 pieces of sushi (Array).
- Compartment 4 holds a tiny mini-sauce container (Embedded sub-document).
- Each compartment holds a completely different food type, but they are all carried in the same container.
(4) Code Examples
Querying by Data Type using the $type Operator
Because data can vary, you can filter documents by their specific BSON type:
// Find all documents where the 'price' field is stored as a String type
db.products.find({ price: { $type: "string" } });
// Find all documents where the 'phone' field is stored as an Array
db.products.find({ phone: { $type: "array" } });
4. Common Mistakes & Pitfalls
Mistake 1: Confusing JavaScript data types with MongoDB BSON data types in your application code
The mistake: Assuming that because JavaScript only has a single Number type (which is a floating-point double), MongoDB will automatically store all numbers as integers if they have no decimals.
Why it's wrong: If you save a JavaScript number 42 to MongoDB using standard drivers, some drivers might save it as a BSON Double (64-bit float) while others save it as an Int32.
This causes mixed types in your collection, which can lead to floating-point rounding errors in calculations or sorting inconsistencies during indexes.
Fix: When saving numbers where precision is critical (like quantities or currencies), use your database driver's explicit type wrappers (e.g. Long(42) or Decimal128("19.99")) to guarantee they are serialized to the correct BSON type.
Mistake 2: Using Invalid BSON Type Numbers in $type Queries
The mistake: Querying { age: { $type: 16 } } without knowing numeric vs string BSON type aliases.
Why it's wrong: BSON types can be referenced by number or string alias (e.g. "int", "double", "string", "objectId", "date"). Using string aliases prevents numeric type code confusion.
Incorrect:
db.users.find({ age: { $type: 16 } }); // Hard to read type code
Fix:
db.users.find({ age: { $type: "int" } }); // Readable string BSON type alias
Mistake 3: Comparing Dissimilar BSON Types in Index Range Queries
The mistake: Querying db.coll.find({ val: { $gt: 10 } }) when val contains mixed strings and numbers.
Why it's wrong: MongoDB defines a strict BSON Type Comparison Order (MinKey < Null < Numbers < Symbol/String < Object < Array < BinData < ObjectId < Date < Timestamp < MaxKey). Comparing mixed types yields unexpected ordering.
Incorrect:
// When val contains "50" (string) and 10 (number)
Fix:
Ensure field values are consistently typed using Schema Validation
5. Practice Exercises
Exercise 1: Inserts with Explicit BSON Type Expressions
Scenario:
Insert a customer document demonstrating explicit BSON types: ObjectId, Date, Int32, and Decimal128.
Requirements:
- Insert document using
NumberInt()andNumberDecimal().
Answer
Implementation
db.customers.insertOne({
_id: new ObjectId(),
name: "Acme Corp",
accountCode: NumberInt(402),
creditLimit: NumberDecimal("50000.00"),
registeredAt: new Date()
});
Technical Explanation
NumberInt()forces BSON 32-bit integer encoding instead of default 64-bit double float.NumberDecimal()forces exact 128-bit IEEE decimal encoding.- Prevents JavaScript driver type coercion implicit errors.
Exercise 2: Querying Fields by BSON Type with $type
Scenario:
Find all documents in orders where field total was incorrectly stored as a string instead of a numeric type.
Requirements:
- Use
$type: "string"operator.
Answer
Exercise 3: Aggregation BSON Type Conversions with $convert
Scenario:
Convert string price fields to BSON Decimal128 inside an aggregation pipeline.
Requirements:
- Use
$convertto transformpriceStringtodecimal.
Answer
Implementation
db.products.aggregate([
{
$project: {
name: 1,
priceDecimal: {
$convert: {
input: "$priceString",
to: "decimal",
onError: NumberDecimal("0.00"),
onNull: NumberDecimal("0.00")
}
}
}
}
]);
Technical Explanation
$convertperforms explicit type conversions inside aggregation pipeline stages.onErrorhandles unparseable string values gracefully without aborting the pipeline.onNullhandles missing or null fields.
6. Related Terms
- BSON (Binary JSON) — The binary serialization.
- String — The text type.
- Number Types (
Int32,Int64/Long,Double,Decimal128) — The numeric types. - Field — Related concept: Field.
BinaryData — Related concept:BinaryData.- Boolean — Related concept: Boolean.
- Date — Related concept: Date.
null— Related concept:null.- Schema Validation (
$jsonSchema) — Related concept: Schema Validation ($jsonSchema).
7. Key Takeaways
- BSON enforces a type system containing 19 distinct type identifiers.
- Expands basic JSON types to include dates, decimal128, and object IDs.
- Helps MongoDB parse and sort data fields efficiently on disk.
- Query documents by type values using the
$typequery operator. - JavaScript numbers default to doubles; wrap them to store exact integers.
- Consistent BSON type choices are required to optimize index scans.