Study guide

5.4 Specialized Index Types: TTL, Partial, Unique & Text

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

5.4 Specialized Index Types: TTL, Partial, Unique & Text

Key Takeaways Explain This Topic AI

TTL (Time-To-Live) indexes automatically delete documents after a specified duration using a background thread running every 60 seconds; they must be single-field Date indexes and cannot be compound or built on '_id'.

Partial indexes index only documents matching a specified 'partialFilterExpression', drastically reducing index memory footprint and write overhead.

Unique indexes reject duplicate key values; combining unique constraints with partialFilterExpression allows enforcing uniqueness on populated fields while ignoring missing or null fields.

A collection can have at most ONE Text index, which supports full-text search, tokenization, language stemming, and relevance sorting via '{ score: { $meta: "textScore" } }'.

2dsphere geospatial indexes index GeoJSON geometry on an Earth-like sphere using [longitude, latitude] coordinate pairs, enabling proximity queries with $near and containment queries with $geoWithin.

Last updated: September 2026

Specialized Index Types: TTL, Partial, Unique & Text

Exam Focus: The MongoDB Certified Associate Developer Exam tests the exact configuration parameters, mechanics, and limitations of specialized index types: TTL index date requirements and 60-second background thread purge cycles, Partial Index partialFilterExpression query matching rules, Unique Index null-handling and Partial Unique patterns, Text Index single-index limits and $text / textScore syntax, and 2dsphere GeoJSON coordinate ordering ( [longitude, latitude] ).

1. Time-To-Live (TTL) Indexes

A TTL (Time-To-Live) Index is a specialized single-field index that automatically purges documents from a collection after a specified amount of time. TTL indexes are ideal for transient operational data such as user authentication sessions, temporary verification tokens, machine telemetry caches, and ephemeral event logs.

  • Syntax & Configuration // Expire documents 3600 seconds (1 hour) after the 'created_at' timestamp
  • db.user_sessions.createIndex(
  • { created_at: 1 },
  • { expireAfterSeconds: 3600 }
  • );
  • Fixed-Interval Expiration vs. Dynamic Custom Expiration

Fixed-Interval Expiration: As shown above, every document expires when current_time >= created_at + expireAfterSeconds .

Dynamic Custom Expiration (Per-Document TTL): Set expireAfterSeconds: 0 and store the explicit future expiration date in each document's Date field: // Create dynamic TTL index

db.coupons.createIndex({ expires_at: 1 }, { expireAfterSeconds: 0 });

  • // Document with custom future expiration date
  • db.coupons.insertOne({
  • code: "SPRING2026",
  • expires_at: ISODate("2026-09-15T00:00:00Z") // Purged after this exact instant
  • });
  • Critical TTL Rules & Limitations (High-Yield Exam Points)

BSON Date Type Requirement: The indexed field must contain a BSON Date ( ISODate ) or an array of BSON Dates. If the field contains a string, timestamp, integer, or null, the document will never be expired.

Single-Field Only: TTL indexes cannot be compound indexes .

Forbidden on _id : You cannot build a TTL index on the primary key _id .

60-Second Background Thread: Document deletion is managed by an internal background thread that executes once every 60 seconds . Therefore, document expiration is not instantaneous; a document may remain visible for up to 60 seconds after its expiration threshold.

Capped Collections Incompatibility: TTL indexes cannot be created on capped collections because capped collections prohibit individual document deletions.

Modifying TTL Thresholds: You can modify expireAfterSeconds on an existing index using the collMod command without dropping and rebuilding the index: db.runCommand({

  • collMod: "user_sessions",
  • index: {
  • keyPattern: { created_at: 1 },
  • expireAfterSeconds: 7200 // Extended to 2 hours
  • }
  • });
  • 2. Partial Indexes

A Partial Index indexes only documents in a collection that satisfy a specified filter expression ( partialFilterExpression ). By omitting documents that are never queried, partial indexes reduce index size in RAM, minimize disk usage, and cut write maintenance overhead.

  • Syntax // Index 'email' ONLY for documents where status is 'ACTIVE'
  • db.users.createIndex(
  • { email: 1 },
  • { partialFilterExpression: { status: "ACTIVE" } }
  • );
  • Query Utilization Rules for Partial Indexes

For MongoDB to use a partial index during query execution, the query filter must be a guaranteed subset of the partialFilterExpression : // Uses the partial index (filter explicitly includes status: "ACTIVE"):

db.users.find({ email: "alex@example.com", status: "ACTIVE" });

// CANNOT use the partial index (filter does not guarantee status is "ACTIVE"):

  • db.users.find({ email: "alex@example.com" }); // Triggers COLLSCAN
  • Allowed Operators in partialFilterExpression

The partialFilterExpression supports: $eq , $exists: true , $gt , $gte , $lt , $lte , $type , and $and at the top level. Operators such as $expr , $where , $text , and $regex are not permitted.

3. Unique Indexes & The Partial Unique Pattern

A Unique Index guarantees that the indexed field does not store duplicate values across the collection, rejecting any write operation that violates uniqueness with an E11000 duplicate key error .

  • Syntax db.accounts.createIndex({ username: 1 }, { unique: true });
  • The Missing/Null Field Problem in Unique Indexes

In MongoDB, if a document does not contain an indexed field, MongoDB stores null as the index entry. Consequently, in a standard unique index, you can insert at most ONE document that lacks the indexed field . A second insert with a missing or null field throws an E11000 duplicate key error on { field: null } !

The Solution: Partial Unique Indexes (Modern Best Practice)

To enforce uniqueness on a field when present while allowing multiple documents to omit the field, combine unique: true with a partialFilterExpression : // Allow multiple users without phone numbers, but enforce uniqueness for all existing phones

  • db.users.createIndex(
  • { phone_number: 1 },
  • {
  • unique: true,
  • partialFilterExpression: { phone_number: { $type: "string" } }
  • }
  • );

Tip

Partial Unique vs Sparse Indexes: While legacy MongoDB supported sparse: true indexes, Partial Unique indexes are strictly preferred because sparse indexes only check field existence ( $exists ), whereas partialFilterExpression allows fine-grained type and value constraints.

4. Text Indexes & Full-Text Search

MongoDB provides Text Indexes to support text search queries on string content, featuring natural language tokenization, stemming (e.g., matching "running" to "run"), and case-insensitive matching.

  • Key Rules & Syntax // Create a text index on multiple string fields
  • db.articles.createIndex(
  • { title: "text", body: "text" },
  • { weights: { title: 10, body: 1 }, name: "idx_article_text_search" }
  • );

Single Text Index Limit: A collection can have at most ONE text index . However, a single text index can compound multiple fields (compound text index) or index all string fields using wildcard syntax ( { "$**": "text" } ).

Executing Queries with $text and $search : // Search for articles containing 'mongodb' AND 'performance', but NOT 'legacy'

  • db.articles.find({
  • $text: { $search: "mongodb performance -legacy" }
  • });

Relevance Sorting via textScore : MongoDB computes a numerical relevance score for each matching document. You can project and sort by this score using $meta: "textScore" : db.articles.find(

  • { $text: { $search: "wiredtiger optimization" } },
  • { score: { $meta: "textScore" } }
  • ).sort({
  • score: { $meta: "textScore" }
  • });
  • 5. Geospatial 2dsphere Indexes

A 2dsphere Index supports queries that calculate geometries on an Earth-like sphere using WGS84 coordinates.

Coordinate Order: [ Longitude, Latitude ]

Warning

Critical Exam Rule: GeoJSON coordinate arrays in MongoDB strictly follow the order: [ Longitude, Latitude ] (X before Y). Reversing the coordinates ( [ Lat, Long ] ) will store invalid coordinates or cause queries to fail. // Document containing GeoJSON Point

  • db.places.insertOne({
  • name: "Central Park",
  • location: {
  • type: "Point",
  • coordinates: [ -73.9654, 40.7829 ] // [ Longitude, Latitude ]
  • }
  • });
  • // Create 2dsphere index
  • db.places.createIndex({ location: "2dsphere" });
  • // Proximity search: Find places within 5,000 meters
  • db.places.find({
  • location: {
  • $near: {
  • $geometry: { type: "Point", coordinates: [ -73.9654, 40.7829 ] },
  • $maxDistance: 5000
  • }
  • }
  • });
  • Specialized Index Comparison Matrix
  • Index Type Primary Use Case Key Configuration Option Critical Restrictions
  • TTL Auto-purging transient data expireAfterSeconds: <N> Single Date field only; 60s purge loop; no capped/ _id

Partial Indexing selective subsets partialFilterExpression: <query> Queries must guarantee filter subset to utilize index

  • Unique Enforcing uniqueness unique: true Multiple nulls conflict without partial filter
  • Text Full-text tokenized search { field: "text" } Maximum 1 text index per collection
  • 2dsphere Geospatial spherical search { field: "2dsphere" } Strict [ Longitude, Latitude ] coordinate ordering

Loading diagram... Specialized Index Architectural Selection Flowchart