This chapter follows Transactions in MongoDB.
Regex and $text on self-hosted Community
Regex on arbitrary fields ({ title: { $regex: /mongo/i } }) is flexible but often cannot use indexes efficiently unless anchored to a prefix.
Text indexes support the $text operator and a single text index per collection:
db.articles.createIndex({ title: 'text', body: 'text' })db.articles.find({ $text: { $search: 'aggregation framework' } })Text search is language-aware but limited compared to dedicated search engines—no rich facets, fuzzy tuning, or autocomplete in one package.
Use regex and $text for simple filters; move to Atlas Search when relevance ranking and analyzers matter.
Atlas Search overview
Atlas Search (Lucene-backed) runs on Atlas and on Atlas Local (mongodb/mongodb-atlas-local) for development. It uses search indexes separate from standard MongoDB indexes and the $search aggregation stage.
Run Atlas Local for this chapter:
docker run -p 27017:27017 -p 8080:8080 mongodb/mongodb-atlas-localConnect with the URI printed in the container logs.
Define a search index
Example index JSON (stored on the search node):
{ "mappings": { "dynamic": false, "fields": { "title": { "type": "string", "analyzer": "lucene.standard" }, "body": { "type": "string", "analyzer": "lucene.english" } } }}Create from TypeScript on Atlas (Search Index API or createSearchIndexes command depending on deployment):
await db.collection('articles').createSearchIndex({ name: 'articles_default', definition: { mappings: { dynamic: false, fields: { title: { type: 'string', analyzer: 'lucene.standard' }, body: { type: 'string', analyzer: 'lucene.english' }, }, }, },});Wait until index status is READY before querying.
$search queries
Basic text search:
db.articles.aggregate([ { $search: { index: 'articles_default', text: { query: 'vector embeddings', path: ['title', 'body'] }, }, }, { $limit: 10 }, { $project: { title: 1, score: { $meta: 'searchScore' } } },])Compound boolean queries combine must/should/mustNot:
{ $search: { index: 'articles_default', compound: { must: [{ text: { query: 'mongodb', path: 'title' } }], should: [{ text: { query: 'atlas', path: 'body', fuzzy: { maxEdits: 1 } } }], }, },}Autocomplete uses the autocomplete field type in the index definition and matching operator in queries.
Highlights, facets, and scoring
Add highlights:
{ $search: { index: 'articles_default', text: { query: 'pagination', path: 'body' }, highlight: { path: 'body' }, },}Faceted counts with $searchMeta:
{ $searchMeta: { index: 'articles_default', facet: { operator: { text: { query: 'database', path: 'body' } }, facets: { categoryFacet: { type: 'string', path: 'category', numBuckets: 10 } }, }, },}Project searchScore via { $meta: 'searchScore' } to sort by relevance.
Paginate with searchAfter
For stable cursor pagination through search results, use searchAfter with the sort values from the previous page (similar in spirit to keyset pagination):
{ $search: { index: 'articles_default', text: { query: 'mongodb', path: 'title' }, sort: { score: { $meta: 'searchScore' }, _id: 1 }, searchAfter: '<token from previous page>', },}Check your understanding
Question 1 of 5
0 of 5 checked