Note
This page describes text query capabilities for self-managed (non-Atlas) deployments. For data hosted on MongoDB, MongoDB also offers an improved full-text query solution, MongoDB Search and a vector search solution, Vector Search.
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 Search 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.
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 Search 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" } } )