Note
MongoDB offers an improved full-text search solution, MongoDB Search, and semantic search solution, MongoDB Vector Search. We recommend using the
$search, $searchMeta, or $vectorSearch
stages, instead of the $text operator.
This page describes the $text operator for self-managed deployments.
Definition
$text$textperforms a text query on fields indexed with a text index.
Compatibility
You can use $text for deployments hosted in the following
environments:
MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud
MongoDB Enterprise: The subscription-based, self-managed version of MongoDB
MongoDB Community: The source-available, free-to-use, and self-managed version of MongoDB
Syntax
A $text expression has the following syntax:
{ $text: { $search: <string>, $language: <string>, $caseSensitive: <boolean>, $diacriticSensitive: <boolean> } }
The $text operator accepts these fields:
Field | Type | Description |
|---|---|---|
| string | A string of terms that MongoDB parses and uses to query
the text index. MongoDB performs a logical |
| string | Optional. The language that determines the stop words, stemmer, and tokenizer rules. Defaults to the index language. For supported languages, see $text Query Languages on Self-Managed Deployments. If you specify a |
| boolean | Optional. Enables case sensitivity. Defaults to |
| boolean | Optional. Enables diacritic sensitivity for version 3
text indexes. Defaults to |
By default, $text does not sort results by score. See
Text Score for details on score sorting.
Behavior
Restrictions
A query can specify only one
$textexpression.$textcannot appear in$norexpressions.$textcannot appear in$elemMatchquery or projection expressions.All
$orclauses must be indexed to use$text.If a query includes a
$textexpression, you cannot usehint()to specify which index to use for the query.Queries with
$textcannot use$naturalsort.You cannot combine the
$textexpression, which requires a special text index, with a query operator that requires a different type of special index. For example you cannot combine$textexpression with the$nearoperator.Views do not support
$text.Stable API V1 does not support
$textfor index creation.
If using the $text operator in aggregation, the following
restrictions also apply.
The
$matchstage that includes a$textmust be the first stage in the pipeline.A
$textoperator can only occur once in the stage.The
$textoperator expression cannot appear in$oror$notexpressions.$text, by default, does not return the matching documents in order of matching scores. To sort by descending score, use the$metaaggregation expression in the$sortstage.
$search Field
In the $search field, specify the words that MongoDB uses to
query the text index.
Note
The $search field differs from the MongoDB Atlas $search
aggregation stage.
The $search stage provides full-text search and is
available only on MongoDB Atlas.
Exact Strings
To match an exact multi-word string instead of individual terms,
enclose the string in escaped double quotes (\"): as in:
"\"ssl certificate\""
If the $search string of a $text operation includes a multi-word string
and individual terms, $text only matches the documents that include the
multi-word string.
For example, this $search string returns documents with the
exact string "ssl certificate":
"\"ssl certificate\" authority key"
Negations
Prefix a word with a hyphen-minus (-) to negate it:
Negated words exclude documents that contain the negated word from the result set.
A string with only negated words matches no documents.
Hyphenated words like
pre-marketare not negations. MongoDB treats the hyphen as a delimiter. To negatemarket, usepre -market.
MongoDB applies all negations to the operation with logical AND.
Match Operation
Stop Words
MongoDB ignores language-specific stop words such as the and
and in English.
Stemmed Words
With case and diacritic insensitivity, $text matches the
complete stemmed word. If a document field contains
blueberry, a $search term of blue does not match.
However, blueberry or blueberries do match.
Case Sensitivity and Stemmed Words
With case sensitivity enabled ($caseSensitive: true), if the suffix stem
contains uppercase letters, $text matches the exact word.
Diacritic Sensitivity and Stemmed Words
With diacritic sensitivity enabled
($diacriticSensitive: true), if the suffix stem contains
diacritic marks, $text matches the exact word.
Case Insensitivity
$text defaults to the case insensitivity of the text index:
The version 3 text index is case insensitive for Latin characters with or without diacritics and non-Latin alphabets like Cyrillic.
Earlier versions are case insensitive for Latin characters without diacritics (
[A-z]).
Enabling Case Sensitivity
Specify $caseSensitive: true to enable case sensitivity when
the text index is case insensitive.
Case Sensitivity Process
When $caseSensitive: true and the text index is case
insensitive, $text:
Queries the text index for case-insensitive and diacritic-insensitive matches.
Filters results to return only documents matching the specified case.
When $caseSensitive: true and the suffix stem contains
uppercase letters, $text matches the exact word.
Enabling $caseSensitive: true may reduce performance.
Diacritic Insensitivity
$text defaults to the diacritic insensitivity of the
text index:
Version 3 text index is diacritic insensitive. The index does not distinguish between characters with diacritic marks and their non-marked counterparts (
é,ê,e).Earlier versions are diacritic sensitive.
Enabling Diacritic Sensitivity
Specify $diacriticSensitive: true to enable diacritic
sensitivity with version 3 text indexes.
Earlier text index versions are always diacritic sensitive, so
$diacriticSensitive has no effect.
Diacritic Sensitivity Process
With version 3 text indexes and $diacriticSensitive: true,
$text:
Queries the diacritic-insensitive text index.
Filters results to return only documents matching the diacritic marks in the specified terms.
Enabling $diacriticSensitive: true may reduce performance.
With earlier text index versions, $diacriticSensitive: true
queries the already diacritic-sensitive text index.
When $diacriticSensitive: true and the suffix stem contains
diacritic marks, $text matches the exact word.
Text Score
The $text operator assigns a score to each result document. The
score represents the relevance of a document to a given query. The score
can be part of a sort() method specification as well as part of the
projection expression. The { $meta: "textScore" } expression
provides information on the processing of the $text operation. See
$meta projection operator for details on accessing the score for projection or sort.
Memory Limits
Changed in version 8.3.
Starting in MongoDB 8.3, the query engine limits the TextOr stage
memory usage to 100 megabytes. The TextOr stage processes
$text queries that read text score metadata. For example,
TextOr processes queries that sort results by text score. If the
TextOr stage exceeds this limit:
If
allowDiskUseistrue, the stage spills intermediate results to disk.If
allowDiskUseisfalse, the query fails with an exceeded memory limit error.
In earlier versions, the TextOr stage had no memory limit and
consumed RAM without restrictions, risking out-of-memory (OOM)
errors.
Examples
The examples on this page use data from the sample_mflix sample dataset. For details on how to load this dataset into your self-managed MongoDB deployment, see Load the sample dataset. If you made any modifications to the sample databases, you may need to drop and recreate the databases to run the examples on this page.
The examples assume a version 3 text
index on the title and fullplot fields:
db.movies.createIndex( { title: "text", fullplot: "text" } )
Search for a Single Word
This example specifies baseball in the $search string. The
query returns documents containing the stemmed version of
baseball in the indexed title or fullplot fields:
db.movies.find( { $text: { $search: "baseball" }, runtime: { $gt: 1000 } }, { _id: 0, title: 1, year: 1, runtime: 1 } )
[ { title: 'Baseball', year: 1994, runtime: 1140 } ]
Match Any Search Term
A space-delimited $search string performs a logical OR on
each term. MongoDB returns documents containing any of the terms.
This example specifies two space-delimited terms. The query returns
documents containing the stemmed versions of baseball or
colorado in the indexed title or fullplot fields:
db.movies.find( { $text: { $search: "baseball colorado" }, runtime: { $gt: 1000 } }, { _id: 0, title: 1, year: 1, runtime: 1, fullplot: 1 } )
[ { runtime: 1140, title: 'Baseball', fullplot: 'Ken Burns relates the history of baseball in a fashion similar to that of his Civil War mini series. Old-time photos and illustrations depict the games early years, while newsreels and video clips highlight more recent developments. Players and participants speak in their own words, and sports writers and broadcasters offer commentary on the sport and events they witnessed.', year: 1994 }, { runtime: 1256, title: 'Centennial', fullplot: 'This is the story of the evolution of the town Centennial, Colorado. It follows the paths of dozens of people who come to the area for many reasons: money, freedom, or crime. It also shows the bigoted treatment of the Native Indians by the advancing US colonists. It is topped off with a murder mystery that takes 100 years to solve.', year: 1978 } ]
Search for an Exact String
Escape the quotes to match an exact multi-word string.
This example matches the exact phrase ken burns:
db.movies.find( { $text: { $search: "\"ken burns\"" }, runtime: { $gt: 1000 } }, { _id: 0, title: 1, year: 1, runtime: 1, fullplot: 1 } )
[ { runtime: 1140, title: 'Baseball', fullplot: 'Ken Burns relates the history of baseball in a fashion similar to that of his Civil War mini series. Old-time photos and illustrations depict the games early years, while newsreels and video clips highlight more recent developments. Players and participants speak in their own words, and sports writers and broadcasters offer commentary on the sport and events they witnessed.', year: 1994 } ]
This example performs a logical OR of two exact strings:
db.movies.find( { $text: { $search: "\'ken burns\' \'centennial\'" }, runtime: { $gt: 1000 } }, { _id: 0, title: 1, year: 1, runtime: 1, fullplot: 1 } )
[ { runtime: 1140, title: 'Baseball', fullplot: 'Ken Burns relates the history of baseball in a fashion similar to that of his Civil War mini series. Old-time photos and illustrations depict the games early years, while newsreels and video clips highlight more recent developments. Players and participants speak in their own words, and sports writers and broadcasters offer commentary on the sport and events they witnessed.', year: 1994 }, { runtime: 1256, title: 'Centennial', fullplot: 'This is the story of the evolution of the town Centennial, Colorado. It follows the paths of dozens of people who come to the area for many reasons: money, freedom, or crime. It also shows the bigoted treatment of the Native Indians by the advancing US colonists. It is topped off with a murder mystery that takes 100 years to solve.', year: 1978 } ]
Exclude Documents That Contain a Term
Prefix a term with - to exclude documents containing that term.
This example matches documents containing baseball or
colorado but not sport (stemmed versions):
db.movies.find( { $text: { $search: "baseball colorado -sport" }, runtime: { $gt: 1000 } }, { _id: 0, title: 1, year: 1, runtime: 1 } )
[ { title: 'Centennial', year: 1978, runtime: 1256 } ]
Relevance Score Examples
Return the Relevance Score
This example queries for baseball and uses
$meta to append the relevance score to each
matching document. The returned document includes a score
field with the relevance score:
db.movies.find( { $text: { $search: "baseball" }, runtime: { $gt: 1000 } }, { _id: 0, title: 1, year: 1, score: { $meta: "textScore" } } )
[ { title: 'Baseball', year: 1994, score: ... } ]
Return Top 2 Matching Documents
Use limit() with sort() to
return the top matching documents.
This example queries for baseball or colorado, sorts by
descending score, and limits results to the top two documents:
db.movies.find( { $text: { $search: "baseball colorado" }, runtime: { $gt: 1000 } }, { _id: 0, title: 1, year: 1, score: { $meta: "textScore" } } ).sort( { score: { $meta: "textScore" } } ).limit(2)
[ { title: 'Baseball', year: 1994, score: ... }, { title: 'Centennial', year: 1978, score: ... } ]
Combine $text with Other Query and Sort Operations
This example matches documents where runtime is greater
than 1000 and the indexed fields contain baseball or
colorado. It sorts by ascending year, then descending
relevance score:
db.movies.find( { runtime: { $gt: 1000 }, $text: { $search: "baseball colorado" } }, { _id: 0, title: 1, year: 1, score: { $meta: "textScore" } } ).sort( { year: 1, score: { $meta: "textScore" } } )
[ { title: 'Centennial', year: 1978, score: ... }, { title: 'Baseball', year: 1994, score: ... } ]
Query a Different Language
The rest of the examples on this page use an articles collection with a
version 3 text index on subject:
db.articles.createIndex( { subject: "text" } )
The collection contains the following documents:
db.articles.insertMany( [ { _id: 1, subject: "coffee", author: "xyz", views: 50 }, { _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 }, { _id: 3, subject: "Baking a cake", author: "abc", views: 90 }, { _id: 4, subject: "baking", author: "xyz", views: 100 }, { _id: 5, subject: "Café Con Leche", author: "abc", views: 200 }, { _id: 6, subject: "Сырники", author: "jkl", views: 80 }, { _id: 7, subject: "coffee and cream", author: "efg", views: 10 }, { _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 } ] )
Use $language to specify the language that determines stop
words, stemmer, and tokenizer rules for the $search string.
If you specify a default_language value of none, the text index
parses through each word in the field, including stop words, and ignores
suffix stemming.
This example specifies es (Spanish) as the language:
db.articles.find( { $text: { $search: "leche", $language: "es" } } )
[ { _id: 5, subject: 'Café Con Leche', author: 'abc', views: 200 }, { _id: 8, subject: 'Cafe con Leche', author: 'xyz', views: 10 } ]
You can also specify languages by name, such as spanish. See
$text Query Languages on Self-Managed Deployments for supported languages.
Sort by Relevance Score
You can specify the { $meta: "textScore" }
expression in the sort() without also specifying
the expression in the projection. For example:
db.articles.find( { $text: { $search: "cake" } } ).sort( { score: { $meta: "textScore" } } )
As a result, you can sort the resulting documents by their relevance
without projecting the textScore.
If you include the { $meta: "textScore" }
expression in both the projection and
sort(), the projection and sort documents can have
different field names for the expression. For example, in the
following operation, the projection uses a field named score for
the expression and the sort() uses the field named
ignoredName:
db.articles.find( { $text: { $search: "cake" } }, { score: { $meta: "textScore" } } ).sort( { ignoredName: { $meta: "textScore" } } )
Case and Diacritic Insensitivity
$text defaults to the case and diacritic insensitivity of the
text index. Version 3 text indexes are diacritic insensitive and
case insensitive for Latin characters with diacritics and non-Latin
alphabets like Cyrillic. See text Index Case Insensitivity and text Index Diacritic
Insensitivity.
This example performs a case and diacritic insensitive query. Using version 3 text indexes, the query matches documents containing the stemmed versions of the search terms:
db.articles.find( { $text: { $search: "сы́рники CAFÉS" } } )
[ { _id: 6, subject: 'Сырники', author: 'jkl', views: 80 }, { _id: 5, subject: 'Café Con Leche', author: 'abc', views: 200 }, { _id: 8, subject: 'Cafe con Leche', author: 'xyz', views: 10 } ]
Earlier text index versions would not match any documents.
Case Sensitivity
Enable case sensitivity with $caseSensitive: true. This may
reduce performance.
Case-Sensitive Term Search
This example performs a case-sensitive query for Coffee:
db.articles.find( { $text: { $search: "Coffee", $caseSensitive: true } } )
[ { _id: 2, subject: 'Coffee Shopping', author: 'efg', views: 5 } ]
Case-Sensitive Exact String Search
This example performs a case-sensitive query for an exact multi-word string:
db.articles.find( { $text: { $search: "\"Café Con Leche\"", $caseSensitive: true } } )
[ { _id: 5, subject: 'Café Con Leche', author: 'abc', views: 200 } ]
Case-Sensitive Negated Term Search
You can use case sensitivity with negated terms (terms prefixed
with -).
This example performs a case-sensitive query for documents
containing Coffee but not shop (stemmed versions):
db.articles.find( { $text: { $search: "Coffee -shop", $caseSensitive: true } } )
[ { _id: 2, subject: 'Coffee Shopping', author: 'efg', views: 5 } ]
Diacritic Sensitivity
Enable diacritic sensitivity with version 3 text indexes using $diacriticSensitive: true.
This may reduce performance.
Diacritic-Sensitive Term Search
This example performs a diacritic-sensitive query for CAFÉ
(stemmed version):
db.articles.find( { $text: { $search: "CAFÉ", $diacriticSensitive: true } } )
[ { _id: 5, subject: 'Café Con Leche', author: 'abc', views: 200 } ]
Diacritic-Sensitive Negated Term Search
You can use diacritic sensitivity with negated terms (terms
prefixed with -).
This example performs a diacritic-sensitive query for documents
containing leches but not cafés (stemmed versions):
db.articles.find( { $text: { $search: "leches -cafés", $diacriticSensitive: true } } )
[ { _id: 8, subject: 'Cafe con Leche', author: 'xyz', views: 10 } ]