1.2 Databases, Collections & Schema Flexibility
Key Takeaways
- A MongoDB namespace is the fully qualified identifier formatted as <database>.<collection>, strictly limited to 255 bytes in WiredTiger.
- System-reserved databases include `admin` (auth and cluster admin), `local` (instance-specific, non-replicated oplog), and `config` (sharded cluster metadata).
- Polymorphic collections allow documents with heterogeneous structures to coexist, while `{ field: null }` queries match both explicit nulls and missing fields (exact null match requires `{ field: { $type: 10 } }`).
- Capped collections are fixed-size FIFO circular buffers where document deletion (deleteOne/deleteMany) is strictly prohibited and updates cannot increase document byte size.
- Time-Series collections optimize high-frequency temporal data streams via columnar bucketing configured with `timeField`, optional `metaField`, and `granularity`.
Databases, Collections & Schema Flexibility
Exam Focus: The Associate Developer Exam tests namespace boundaries (255-byte limit), reserved database semantics (
admin,local,config), query differentiation between missing and explicit null fields ($existsvs$type), capped collection operational constraints (FIFO overwrites, prohibition of deletions, tailable cursors), and time-series collection parameter configuration (timeField,metaField,granularity).
Namespace Architecture & Naming Constraints
MongoDB organizes data into a three-tier hierarchy: Databases, Collections, and Documents.
A Namespace is the fully qualified identifier for a collection or index, constructed by concatenating the database name, a dot separator, and the collection name:
The 255-Byte Namespace Limit
In the WiredTiger storage engine, the maximum allowable length for a namespace is 255 bytes. This byte count includes the database name, the dot separator, the collection name, and any internal index namespace prefixes (e.g., ecommerce_production.customer_order_records.$_id_). Exceeding 255 bytes results in namespace creation errors.
Database & Collection Naming Rules
- Database Naming Rules:
- Database names are case-sensitive (
analyticsDBis distinct fromanalyticsdb). - Maximum length is 63 characters.
- Cannot contain the null byte (
\0), spaces, or any of the following restricted ASCII characters:/,\,.,",*,<,>,:,|,?,$. Cannot be empty.
- Database names are case-sensitive (
- Collection Naming Rules:
- Collection names are case-sensitive.
- Cannot contain the null byte (
\0). - Cannot start with the reserved prefix
system.(reserved for internal engine collections such assystem.views,system.profile,system.buckets). - Cannot contain the
$character in general user collection names.
Reserved Databases & Internal Namespaces
MongoDB maintains several reserved system databases with specialized cluster and replication roles:
| Reserved Database | Replication Behavior | Primary Role & Description |
|---|---|---|
admin | Replicated across cluster | Cluster Administration & Auth: Stores system-wide user credentials, custom role definitions, authentication configurations, and cluster-wide administrative commands. |
local | Never replicated (Instance-local) | Instance Diagnostics & Oplog: Stores data specific to that individual mongod instance. Contains oplog.rs (the replication operation log) and startup_log. Data in local is never copied to other replica set members. |
config | Replicated across Config Servers | Sharding Metadata: Stores the master routing table for sharded clusters, tracking chunk ranges, shard mappings, and cluster configuration settings. |
test | Replicated (if user creates it) | Default scratchpad database loaded when launching mongosh without specifying a database name. |
[!IMPORTANT] Critical Exam Rule: The
localdatabase is strictly non-replicated. Any collection created insidelocalexists only on that single physical node and will never be synchronized to secondary members.
Schema Flexibility: Polymorphism & Schema Versioning
Unlike relational databases which enforce rigid schema constraints across all rows in a table, MongoDB provides dynamic schema flexibility. Collections do not dictate document structure at the storage layer by default.
1. Polymorphic Collections
A single collection can store polymorphic documents—documents that share common root metadata but possess varying attributes, nested structures, or data types based on their specific entity sub-type. For instance, an e-commerce catalog collection can store books, apparel, and digital software side-by-side:
// Book entity in 'products' collection
db.products.insertOne({
_id: ObjectId("66d57a01a1b2c3d4e5f60001"),
type: "book",
title: "Designing Data-Intensive Applications",
isbn: "978-1449373320",
pages: NumberInt(616)
});
// Apparel entity in the SAME 'products' collection
db.products.insertOne({
_id: ObjectId("66d57a01a1b2c3d4e5f60002"),
type: "apparel",
title: "MongoDB Engineering Hoodie",
sizes: ["M", "L", "XL"],
material: "100% Organic Cotton"
});
2. The Schema Versioning Pattern
As applications evolve, document structures change (e.g., merging firstName and lastName into a single fullName field). Instead of running costly offline database migrations that rewrite millions of documents simultaneously, developers use the Schema Versioning Pattern:
// Legacy document (Schema Version 1)
{
_id: ObjectId("..."),
schema_version: 1,
firstName: "Maya",
lastName: "Lin"
}
// Modern document (Schema Version 2)
{
_id: ObjectId("..."),
schema_version: 2,
fullName: "Maya Lin",
contact: { email: "maya.lin@example.com" }
}
The application code handles multiple versions dynamically on read, updating documents to the latest version lazily during subsequent writes (lazy migration).
Querying Missing vs. Null Fields: $exists vs. $type
A classic trap on the MongoDB Associate Developer Exam involves querying documents with missing fields versus explicit BSON null values.
Suppose a collection users contains the following three documents:
{ _id: 1, name: "Alice", phone: "555-0199" } // phone is populated
{ _id: 2, name: "Bob", phone: null } // phone explicitly set to null
{ _id: 3, name: "Carol" } // phone field does not exist
The { field: null } Trap
When you execute the query db.users.find({ phone: null }), MongoDB returns both Bob (_id: 2) and Carol (_id: 3). In MongoDB query semantics, { field: null } evaluates to true if the field contains an explicit null OR if the field is missing entirely from the document!
Differentiating Missing from Explicit Null
To target specific states, you must combine the $exists and $type operators:
| Query Expression | Matches phone: "555" | Matches phone: null | Matches Missing phone | Description & Target |
|---|---|---|---|---|
{ phone: null } | ❌ No | ✅ Yes | ✅ Yes | Matches explicit nulls AND missing fields. |
{ phone: { $exists: true } } | ✅ Yes | ✅ Yes | ❌ No | Matches any document where phone exists, even if null. |
{ phone: { $exists: false } } | ❌ No | ❌ No | ✅ Yes | Matches ONLY documents where phone is absent. |
{ phone: { $type: 10 } } | ❌ No | ✅ Yes | ❌ No | Matches ONLY documents with explicit BSON null (Type 10). |
{ phone: { $type: "null" } } | ❌ No | ✅ Yes | ❌ No | Alias equivalent to Type 10. |
{ phone: null, $exists: true } | ❌ No | ✅ Yes | ❌ No | Matches explicit nulls while filtering out missing fields. |
Capped Collections: High-Throughput FIFO Circular Buffers
A Capped Collection is a fixed-size, circular FIFO (First-In, First-Out) collection designed for high-throughput logging, telemetry buffering, and real-time event streaming. When a capped collection fills its allocated disk space, it automatically overwrites its oldest documents in natural insertion order without index fragmentation.
Creation Syntax
// Create a capped collection of 10 MB with a maximum of 5,000 documents
db.createCollection("system_audit_events", {
capped: true,
size: 10485760, // Mandatory: Maximum size in bytes (10 MB)
max: 5000 // Optional: Maximum number of documents allowed
});
size(Number, Mandatory): The maximum storage quota in bytes allocated for the collection. WiredTiger pre-allocates space.max(Number, Optional): The maximum document count ceiling. If the document count reachesmaxbefore the bytesizeis exhausted, older documents are purged.
Strict Operational Constraints (High-Yield Exam Topics)
- No Individual Document Deletions: You CANNOT execute
deleteOne()ordeleteMany()on a capped collection. Callingdeletethrows an error:cannot remove from a capped collection. To clear a capped collection, you mustdrop()the entire collection and recreate it. - No Size-Expanding Updates: Document updates are permitted ONLY if the updated document does not increase in byte size. An update that causes the document to expand beyond its original on-disk allocation throws a
cannot grow document in capped collectionerror. - Natural Insertion Order: Documents are permanently ordered on disk by insertion sequence. Queries without a
$sortnaturally return documents in chronological insertion order. - Cannot Be Sharded: Capped collections cannot be partitioned across a sharded cluster.
Tailable Cursors
Capped collections support Tailable Cursors (conceptually identical to the Unix tail -f command). Unlike standard cursors which close when the client reaches the end of the result set, a tailable cursor remains open, waiting for new documents to be inserted:
// Opening an awaiting tailable cursor in mongosh / driver
const cursor = db.system_audit_events.find()
.tailable({ awaitData: true });
while (cursor.hasNext()) {
printjson(cursor.next());
}
Time-Series Collections: Optimized Temporal Metric Pipelines
Introduced to natively handle high-frequency sensor telemetry, stock ticks, and IoT metrics, Time-Series Collections store temporal sequences using columnar compressed storage buckets under the hood (managed in internal system.buckets collections).
Creation Syntax
db.createCollection("weather_metrics", {
timeseries: {
timeField: "timestamp", // Mandatory: Top-level date field
metaField: "sensor_metadata", // Optional: Identifying metadata subdocument/string
granularity: "minutes", // Optional: 'seconds' | 'minutes' | 'hours' (default: 'seconds')
bucketMaxSpanSeconds: 3600 // Optional: Max time span per bucket
},
expireAfterSeconds: 2592000 // Optional: TTL automatic expiration (30 days)
});
timeField(String, Mandatory): The name of the top-level document field containing the BSON Date timestamp for the measurement.metaField(String, Optional): The name of the field containing static metadata identifying the source entity (e.g.,{ sensor_id: "SN-882", location: "Building-4" }). MongoDB automatically builds a compound index on{ [metaField]: 1, [timeField]: 1 }.granularity(String, Optional): Defines the sampling frequency:"seconds"(default),"minutes", or"hours". Setting the proper granularity optimizes the internal bucketing interval and maximizes compression.
| Collection Type | Data Ingestion Model | Purge / Deletion Strategy | Sharding Support | Best Use Case |
|---|---|---|---|---|
| Standard | General purpose | Full CRUD (deletions, updates) | ✅ Yes | User profiles, orders, catalogs |
| Capped | High-throughput append-only | Automatic FIFO circular overwrite | ❌ No | System logs, audit trails, event feeds |
| Time-Series | Columnar append-only | TTL index (expireAfterSeconds) | ✅ Yes | IoT telemetry, metrics, financial ticks |
Practical Collection Management in mongosh
use telemetry_db;
// 1. Create a capped audit collection with a 5MB size limit
db.createCollection("app_logs", { capped: true, size: 5242880, max: 10000 });
// 2. Verify capped status
const isCapped = db.app_logs.isCapped();
print("Collection is capped:", isCapped); // true
// 3. Insert telemetry records
db.app_logs.insertOne({ event: "LOGIN_SUCCESS", user_id: 42, timestamp: new Date() });
// 4. Attempting an illegal deletion (Throws MongoServerError: cannot remove from a capped collection)
try {
db.app_logs.deleteOne({ user_id: 42 });
} catch (err) {
print("Caught expected error:", err.message);
}
// 5. Query differentiating null from missing values in user settings
db.user_settings.find({ notification_channel: { $type: "null" } }); // Exact explicit nulls
db.user_settings.find({ notification_channel: { $exists: false } }); // Completely missing
An operational engineering team implements a capped collection to record application security audit logs. Which operation is strictly prohibited and will result in a runtime error when executed against this collection?
A developer runs the query db.orders.find({ discount_code: null }). Which documents in the collection will be returned by this query?
Under the WiredTiger storage engine, what is the maximum allowable namespace length for a MongoDB collection (<database>.<collection>), and what is a forbidden collection naming convention?
When creating a Time-Series collection using db.createCollection('telemetry', { timeseries: { ... } }), which configuration property inside the timeseries option object is mandatory?