Study guide
1.2 Databases, Collections & Schema Flexibility
MongoDB Associate Developer Exam
Track your progress as you read
Finished sections get a check mark.
1 Chapter 1: Document Model & MongoDB Architecture
1.1 Document Model Fundamentals & BSON Data Types 1.2 Databases, Collections & Schema Flexibility 1.3 Distributed Architecture Fundamentals: Replica Sets & Sharded Clusters
2 Chapter 2: CRUD Operations: Create & Read
2.1 Document Insertion Operations 2.2 Query Selectors & Filter Operators 2.3 Array Queries & Element Evaluation 2.4 Projections, Cursor Methods & Collation
3 Chapter 3: CRUD Operations: Update & Delete
3.1 Field Update Operators 3.2 Array Update Operators & Positional Modifiers 3.3 Document Replacement & Deletion Operations 3.4 Atomic Find-and-Modify Operations
4 Chapter 4: Aggregation Framework Mastery
4.1 Pipeline Fundamentals & Core Stages ($match, $project, $addFields) 4.2 Grouping, Reshaping & Array Manipulation ($group, $unwind, $replaceWith) 4.3 Multi-Document Joins & Faceted Pipelines ($lookup, $facet, $bucket) 4.4 Materialization & Window Operations ($out, $merge, $setWindowFields) 4.5 Atlas Search: Search Index Definitions & $search Queries
5 Chapter 5: Indexing Strategies & Performance Optimization
5.1 Index Types & Storage Mechanics 5.2 Compound Indexes & the Equality-Sort-Range (ESR) Rule 5.3 Multikey Indexes & Array Indexing Constraints 5.4 Specialized Index Types: TTL, Partial, Unique & Text 5.5 Query Optimization & Explain Plan Analysis
6 Chapter 6: Data Modeling & Schema Design Patterns
6.1 Embedding vs. Referencing Tradeoffs 6.2 Core Schema Design Patterns 6.3 Schema Validation with JSON Schema
7 Chapter 7: Application Development & Driver Integration
7.1 Connection Strings & Connection Pool Management 7.2 Driver CRUD Paradigms & Object Mapping 7.3 Cursor Batching, Streaming & Memory Handling 7.4 Write Concerns, Read Concerns & Retryable Operations
8 Chapter 8: Developer Tooling & Administration Essentials
8.1 mongosh Scripting & Administrative Commands 8.2 Data Ingestion & Export Utilities 8.3 Backup, Restore & Performance Telemetry 8.4 Atlas Sample Dataset & Data Explorer
1.2 Databases, Collections & Schema Flexibility
Key Takeaways Explain This Topic AI
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 .
Last updated: September 2026
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 ( $exists vs $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: Namespace = ⟨ database ⟩ . ⟨ collection ⟩ \text{Namespace} = \langle\text{database}\rangle\text{.}\langle\text{collection}\rangle Namespace = ⟨ database ⟩ . ⟨ collection ⟩
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 ( analyticsDB is distinct from analyticsdb ).
Maximum length is 63 characters .
Cannot contain the null byte ( \0 ), spaces, or any of the following restricted ASCII characters: / , \ , . , " , * , < , > , : , | , ? , $ . Cannot be empty.
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 as system.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 local database is strictly non-replicated . Any collection created inside local exists 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 reaches max before the byte size is exhausted, older documents are purged.
Strict Operational Constraints (High-Yield Exam Topics)
No Individual Document Deletions: You CANNOT execute deleteOne() or deleteMany() on a capped collection. Calling delete throws an error: cannot remove from a capped collection . To clear a capped collection, you must drop() 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 collection error.
Natural Insertion Order: Documents are permanently ordered on disk by insertion sequence. Queries without a $sort naturally 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