Study guide
4.5 Atlas Search: Search Index Definitions & $search Queries
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
4.5 Atlas Search: Search Index Definitions & $search Queries
Key Takeaways Explain This Topic AI
Exam objectives 2.18 and 2.19 sit inside the 51% CRUD domain and test MongoDB Search (Atlas Search), not the MongoDB Query Language.
A search index is a Lucene inverted index maintained asynchronously by the mongot process; it is eventually consistent and is never used by the query planner for find().
db.collection.createSearchIndex() names the index 'default' when the name argument is omitted and defaults the type to 'search'; with dynamic: false, a mappings.fields object is required.
$search and $searchMeta must be the first stage of an aggregation pipeline, with the sole exception of the first stage inside a $lookup sub-pipeline in MongoDB 6.0 and later.
Inside compound, must and should contribute to the relevance score, mustNot excludes documents, and filter constrains results without affecting the score exposed via $meta: 'searchScore'.
Last updated: September 2026
4.5 Atlas Search: Search Index Definitions & $search Queries
The official MongoDB Associate Developer exam guide places two objectives inside the 51% CRUD domain that are not about the MongoDB Query Language at all : objective 2.18 asks you to identify the correct command for defining a search index , and objective 2.19 asks you to identify the correct search query . Both refer to MongoDB Search (historically branded Atlas Search ) — a relevance-based, full-text search engine that runs alongside the database. Because these two objectives sit in the heaviest-weighted domain, skipping them is one of the most common ways well-prepared candidates lose points.
1. A Search Index Is Not a Database Index
This is the single most important distinction in this section, and the exam tests it directly.
A database index (what db.collection.createIndex() builds) is a B-tree keyed on field values. It is updated synchronously , inside the same write operation that modifies the document, and it is consumed by the query planner to turn a COLLSCAN into an IXSCAN .
A search index is an inverted index — a mapping from terms to the documents containing those terms — built on Apache Lucene . It is maintained by a separate process called mongot , which follows the collection's change stream and updates the Lucene index asynchronously . Two consequences follow directly:
Search indexes are eventually consistent . A document you just inserted may not appear in $search results for a short interval. You cannot rely on read-your-own-write behavior.
Search indexes are invisible to the query planner . Creating a search index will never speed up an ordinary find() , and explain() on a find() will never show it.
- Database Index Search Index
- Structure B-tree Lucene inverted index
- Created with createIndex() createSearchIndex()
- Queried with find() , $match $search , $searchMeta
- Update timing Synchronous with the write Asynchronous via mongot
- Used by query planner Yes ( IXSCAN ) No
- Relevance scoring None { $meta: "searchScore" }
- 2. Defining a Search Index (Objective 2.18)
In mongosh , search indexes are created with db.<collection>.createSearchIndex() , available from MongoDB 7.0 (and backported to 6.0.7). The full signature takes three arguments, two of which are optional: db.<collection>.createSearchIndex(
- <name>, // optional string
- <type>, // optional: "search" (default) or "vectorSearch"
- { <definition> } // required
- )
Two defaults are directly examinable:
If you omit name , the index is named default .
If you omit type , the index type is search .
Dynamic Mappings
The simplest definition tells MongoDB Search to index every supported field type automatically: db.movies.createSearchIndex({ mappings: { dynamic: true } })
- // -> creates a search index literally named "default"
- Static Mappings
Static mappings enumerate exactly which fields are indexed and how each is analyzed. This is the production-grade choice: smaller indexes, faster builds, predictable scoring. db.movies.createSearchIndex(
- "movieTitleIdx",
- {
- mappings: {
- dynamic: false,
- fields: {
- title: { type: "string" },
- plot: { type: "string" },
- year: { type: "number" }
- }
- }
- }
- )
Exam trap: when mappings.dynamic is false , mappings.fields is required . A definition of { mappings: { dynamic: false } } with no fields object indexes nothing, and every $search query against it returns zero results — with no error to tell you why.
Search indexes can also be created from the Atlas UI (Search tab → Create Search Index , using either the Visual Editor or the JSON Editor), the Atlas CLI , Compass , the Atlas Admin API , and the official drivers . The equivalent database command is createSearchIndexes . Companion helpers are $listSearchIndexes (an aggregation stage), db.<collection>.updateSearchIndex() , and db.<collection>.dropSearchIndex() .
3. Writing a Search Query (Objective 2.19)
A search query is an aggregation pipeline stage , not a find() filter. MongoDB Search provides two stages:
$search — runs the full-text query and returns the matching documents, ordered by descending relevance.
$searchMeta — returns only metadata about the results (facet buckets, total counts) without returning the documents themselves.
The First-Stage Rule
$search and $searchMeta must be the first stage of the aggregation pipeline. Placing any other stage ahead of them is an error, not a performance problem. This is the most frequently tested fact about search queries: // INVALID — $match precedes $search
- db.movies.aggregate([
- { $match: { year: { $gte: 2000 } } },
- { $search: { text: { query: "space", path: "plot" } } }
- ])
- // VALID — $search first, then filter and shape the results
- db.movies.aggregate([
- { $search: { text: { query: "space", path: "plot" } } },
- { $match: { year: { $gte: 2000 } } },
- { $project: { title: 1, year: 1, score: { $meta: "searchScore" } } },
- { $limit: 10 }
- ])
The one narrow exception, added in MongoDB 6.0: $search may appear as the first stage inside a $lookup sub-pipeline .
Selecting the Index
If the index option is omitted, $search queries the index named default . When you created a named index, you must name it in the query — this mismatch is a classic exam distractor: db.movies.aggregate([
- { $search: { index: "movieTitleIdx", text: { query: "space", path: "title" } } }
- ])
- Common Search Operators
- Operator Purpose
- text Analyzed full-text match; supports fuzzy
- phrase Ordered term sequence, with optional slop
- autocomplete Search-as-you-type against an autocomplete -typed field
- equals Exact match on boolean, number, date, ObjectId, or string token
- range Numeric, date, or string bounds ( gt , gte , lt , lte )
- wildcard / regex Pattern matching against indexed terms
- exists Documents in which the indexed path is present
- compound Combines the above via must , mustNot , should , filter
- Compound Queries and Scoring
compound is where relevance is actually shaped, and each clause behaves differently:
must — the clause is required and contributes to the score .
should — optional; every match raises the score . minimumShouldMatch sets how many should clauses must match.
mustNot — excludes matching documents.
filter — required, but does not affect the score . Use it for hard constraints such as a category or a date window so they cannot distort ranking. db.movies.aggregate([
- { $search: {
- index: "movieTitleIdx",
- compound: {
- must: [ { text: { query: "space", path: "title" } } ],
- should: [ { text: { query: "odyssey", path: "plot" } } ],
- filter: [ { range: { path: "year", gte: 1990 } } ]
- }
- } },
- { $project: { title: 1, score: { $meta: "searchScore" } } }
- ])
Relevance is exposed through the $meta: "searchScore" expression, mirroring the way $text exposes $meta: "textScore" . Results already arrive sorted by descending score, so adding { $sort: { score: -1 } } is redundant unless you are combining scores with other criteria.
4. MongoDB Search vs. $text Full-Text Search
The guide's earlier coverage of text indexes ( createIndex({ field: "text" }) queried with $text ) is a different feature, and the exam will offer one as a distractor for the other.
- $text + text index MongoDB Search
- Created by createIndex({ f: "text" }) createSearchIndex(...)
- Queried by $text inside find() or $match $search / $searchMeta
- Engine MongoDB's own text index Apache Lucene via mongot
- Text indexes per collection One Many search indexes allowed
- Relevance metadata { $meta: "textScore" } { $meta: "searchScore" }
- Fuzzy / autocomplete / highlighting Not supported Supported
- Faceting Not supported $searchMeta with facets
- Stage position Anywhere a filter is valid Must be first
How to read these questions on exam day:
If the stem says "define a search index" , the answer uses createSearchIndex() with a mappings object — not createIndex() , and not a bare field list.
If the stem shows a pipeline, check stage order first . $search anywhere but position one is wrong before you even read the operator.
If the definition sets dynamic: false , confirm a fields object is present.
If the query names an index, confirm that name was actually created; if no name was given at creation, the index is default .
filter clauses inside compound are the correct tool when a constraint must not influence relevance ranking.