Understanding BSON Data Types
1. Understanding Document Structure
| Element | Detail |
| Format | Binary JSON (BSON), little-endian |
| Max document size | 16 MB |
| Max nesting depth | 100 levels |
| Field name limit | No size limit but must be UTF-8; cannot contain \0 |
| Ordering | Field order preserved (unlike JSON objects in some langs) |
| _id field | Required, unique per collection, immutable |
{
"_id": ObjectId("65f0a1b2c3d4e5f6a7b8c9d0"),
"name": "Alice",
"email": "alice@example.com",
"tags": ["admin", "ops"],
"profile": { "age": 30, "city": "NYC" },
"createdAt": ISODate("2026-01-15T10:00:00Z")
}
2. Working with String Type
| Aspect | Detail |
| Encoding | UTF-8 |
| Max length | Bounded by 16MB doc limit |
| BSON type code | 2 ("string") |
| $type alias | "string" |
db.users.find({ name: { $type: "string" } });
db.users.find({ name: /^Ali/i }); // regex on strings
3. Working with Number Types
| Type | BSON code | Constructor | Range |
| Int32 | 16 | NumberInt("42") | ±2.1×10⁹ |
| Int64 (Long) | 18 | NumberLong("9000000000") | ±9.2×10¹⁸ |
| Double | 1 | 3.14 (literal) | IEEE 754 64-bit |
| Decimal128 | 19 | NumberDecimal("9.99") | 34 decimal digits |
Note: Use Decimal128 for monetary values to avoid floating-point rounding.
4. Working with Boolean Type
| Aspect | Detail |
| Values | true, false |
| BSON code | 8 |
| $type alias | "bool" |
| Truthy in $expr | Non-zero numbers, non-empty strings → true |
5. Working with Date Type
| Aspect | Detail |
| Storage | Int64 ms since Unix epoch (UTC) |
| BSON code | 9 |
| Constructors | new Date(), ISODate("2026-01-15") |
| Range | ±290M years from epoch |
| Aggregation | $dateToString, $year, $dateDiff |
db.events.find({ createdAt: { $gte: ISODate("2026-01-01"), $lt: ISODate("2026-02-01") } });
6. Working with ObjectId Type
| Byte Range | Meaning |
| 0-3 | Unix timestamp (seconds, big-endian) |
| 4-8 | Random per-process value |
| 9-11 | Incrementing counter |
const id = new ObjectId();
id.getTimestamp(); // Date object
ObjectId.createFromTime(1700000000); // for time-bounded queries
7. Working with Arrays
| Aspect | Detail |
| BSON code | 4 |
| Storage | Document with stringified numeric keys |
| Multikey indexing | Each element gets an index entry |
| Equality match | Matches arrays containing the value or equal to the array |
| Operators | $all, $elemMatch, $size, $in |
8. Working with Embedded Documents
| Aspect | Detail |
| BSON code | 3 |
| Dot notation | "profile.city" |
| Exact match | Field order & value must match |
| Partial match | Use dot notation: { "profile.age": 30 } |
db.users.find({ "profile.city": "NYC" });
db.users.updateOne({ _id: id }, { $set: { "profile.age": 31 } });
9. Working with Null and Undefined Values
| Type | BSON code | Notes |
| Null | 10 | Use for "no value" |
| Undefined | 6 DEPRECATED | Do not use; not BSON 1.1 |
{x: null} query | - | Matches docs where x is null OR missing |
{x: {$type: 10}} | - | Matches only explicit null |
{x: {$exists: false}} | - | Matches only missing field |
10. Working with Binary Data
| Subtype | Code | Use |
| Generic | 0 | Arbitrary bytes |
| Function | 1 | Reserved |
| UUID | 4 | RFC 4122 UUID |
| MD5 | 5 | Hash storage |
| Encrypted | 6 | CSFLE / Queryable Encryption |
| User-defined | 128+ | Application use |
db.files.insertOne({ _id: UUID(), payload: BinData(0, "SGVsbG8gV29ybGQ=") });
11. Understanding Regular Expression Type
| Flag | Meaning |
| i | Case-insensitive |
| m | Multiline (^ $ per line) |
| x | Extended: ignore whitespace |
| s | . matches newline |
db.products.find({ name: /^iphone/i });
db.products.find({ name: { $regex: "iphone", $options: "i" } });
Note: Anchored prefix patterns (/^abc/) can use B-tree indexes; /abc/i usually cannot.
12. Understanding Timestamp Type
| Aspect | Detail |
| BSON code | 17 |
| Structure | {t: seconds, i: ordinal} (8 bytes) |
| Use | Internal oplog ordering; reserved for system use |
| Constructor | Timestamp(1700000000, 1) |
| vs Date | Date for app data; Timestamp for replication/sharding |