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 following examples use an articles collection with a
version 3 text index on subject:
db.articles.createIndex( { subject: "text" } )
Populate the collection with 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 } ] )
Search for a Single Word
This example specifies coffee in the $search string:
db.articles.find( { $text: { $search: "coffee" } } )
This returns documents containing the stemmed version of
coffee in the indexed subject field:
{ _id: 1, subject: 'coffee', author: 'xyz', views: 50 }, { _id: 7, subject: 'coffee and cream', author: 'efg', views: 10 }, { _id: 2, subject: 'Coffee Shopping', author: 'efg', views: 5 }
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 three space-delimited terms:
db.articles.find( { $text: { $search: "bake coffee cake" } } )
This returns documents containing the stemmed versions of bake or
coffee or cake in the indexed subject field:
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 } { "_id" : 7, "subject" : "coffee and cream", "author" : "efg", "views" : 10 } { "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50 } { "_id" : 3, "subject" : "Baking a cake", "author" : "abc", "views" : 90 } { "_id" : 4, "subject" : "baking", "author" : "xyz", "views" : 100 }
Search for an Exact String
Escape the quotes to match an exact multi-word string.
This example matches the exact string coffee shop:
db.articles.find( { $text: { $search: "\"coffee shop\"" } } )
This operation returns documents that contain the string coffee shop:
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }
This example performs a logical OR of two exact strings:
db.articles.find( { $text: { $search: "\'coffee shop\' \'Cafe con Leche\'" } } )
This returns documents containing either string, including documents with terms from both strings:
[ { _id: 8, subject: 'Cafe con Leche', author: 'xyz', views: 10 }, { _id: 5, subject: 'Café Con Leche', author: 'abc', views: 200 }, { _id: 1, subject: 'coffee', author: 'xyz', views: 50 }, { _id: 7, subject: 'coffee and cream', author: 'efg', views: 10 }, { _id: 2, subject: 'Coffee Shopping', author: 'efg', views: 5 } ]
Exclude Documents That Contain a Term
Prefix a term with - to exclude documents containing that term.
This example matches documents containing coffee but not
shop (stemmed versions):
db.articles.find( { $text: { $search: "coffee -shop" } } )
The operation returns the following documents:
{ "_id" : 7, "subject" : "coffee and cream", "author" : "efg", "views" : 10 } { "_id" : 1, "subject" : "coffee", "author" : "xyz", "views" : 50 }
Query a Different Language
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" } } )
The example returns the following documents:
{ "_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.
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:
db.articles.find( { $text: { $search: "сы́рники CAFÉS" } } )
Using version 3 text indexes, this matches:
{ "_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 } } )
This matches only:
{ "_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 } } )
This matches only:
{ "_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 } } )
This matches:
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg" }
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 } } )
This matches only:
{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc" }
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 } } )
This matches:
{ "_id" : 8, "subject" : "Cafe con Leche", "author" : "xyz" }
Relevance Score Examples
Return the Relevance Score
This example queries for cake and uses $meta to
append the relevance score to each matching document:
db.articles.find( { $text: { $search: "cake" } }, { score: { $meta: "textScore" } } )
The returned document includes a score field with the
relevance score:
{ "_id" : 3, "subject" : "Baking a cake", "author" : "abc", "views" : 90, "score" : 0.75 }
Tip
Sort by Relevance Score
You can specify the
{ $meta: "textScore" }expression in thesort()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 andsort(), the projection and sort documents can have different field names for the expression.For example, in the following operation, the projection uses a field namedscorefor the expression and thesort()uses the field namedignoredName.db.articles.find( { $text: { $search: "cake" } } , { score: { $meta: "textScore" } } ).sort( { ignoredName: { $meta: "textScore" } } )
Tip
Return Top 2 Matching Documents
Use limit() with sort() to
return the top matching documents.
This example queries for coffee, sorts by descending score,
and limits results to the top two documents:
db.articles.find( { $text: { $search: "coffee" } }, { score: { $meta: "textScore" } } ).sort( { score: { $meta: "textScore" } } ).limit(2)
Tip
Combine $text with Other Query and Sort Operations
This example matches documents where author is "xyz" and
subject contains coffee or bake. It sorts by
ascending date, then descending relevance score:
db.articles.find( { author: "xyz", $text: { $search: "coffee bake" } }, { score: { $meta: "textScore" } } ).sort( { date: 1, score: { $meta: "textScore" } } )