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 the content of the 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 a text query document with the following 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 list of stop words for the query and the rules for the stemmer and tokenizer. If unspecified, MongoDB uses the default language of the index. For supported languages, see Text Search Languages on Self-Managed Deployments. If you specify a |
| boolean | Optional. A boolean flag to enable or disable case sensitivity. Defaults to For more information, see Case Insensitivity. |
| boolean | Optional. A boolean flag to enable or disable diacritic sensitivity against version 3 text indexes. Defaults to Text queries against earlier versions of the text index are inherently diacritic sensitive and cannot be diacritic insensitive. As such, the For more information, see Diacritic Insensitivity. |
The $text operator, by default, does not return results sorted in terms of the results' scores. For more information on sorting by the results' scores, see the Text Score documentation.
Behavior
Restrictions
A query can specify, at most, one
$textexpression.$textcannot appear in$norexpressions.$textcannot appear in$elemMatchquery expressions or$elemMatchprojection expressions.To use
$textin an$orexpression, all clauses in the$orarray must be indexed.If a query includes a
$textexpression, you cannot usehint()to specify which index to use for the query.You cannot specify the
$naturalsort order if the query includes a$textexpression.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.$textis unsupported for creating indexes using the Stable API V1.
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 a string of words that the $text operator parses and uses to query the text index.
The $text operator treats most punctuation in the string as delimiters, except a hyphen-minus (-) that negates term or an escaped double quotes \" that specifies an exact string.
Note
The $search field for the $text expression is different than the $search aggregation stage provided by Atlas Search. The $search aggregation stage performs a full-text search on specified fields and is only available on MongoDB Atlas.
Exact Strings
To match on an exact multi-word string, as opposed to 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, the following $search string returns documents that include the exact string "ssl certificate":
"\"ssl certificate\" authority key"
Negations
Prefixing a word with a hyphen-minus (-) negates a word:
The negated word excludes documents that contain the negated word from the result set.
When passed a string that only contains negated words,
$textdoes not match any documents.A hyphenated word, such as
pre-market, is not a negation. If used in a hyphenated word, the$textoperator treats the hyphen-minus (-) as a delimiter. To negate the wordmarketin this instance, include a space betweenpreand-market, i.e.,pre -market.
The $text operator adds all negations to the operation with the logical AND operator.
Match Operation
Stop Words
The $text operator ignores language-specific stop words, such as the and and in English.
Stemmed Words
When you use case insensitivity and diacritic insensitivity, the $text operator matches on the complete stemmed word. If a document field contains the word blueberry, a $text operation with a $search term of blue does not match. However, blueberry or blueberries match.
Case Sensitivity and Stemmed Words
When you use case sensitivity ($caseSensitive: true), if the suffix stem contains uppercase letters, the $text operator matches on the exact word.
Diacritic Sensitivity and Stemmed Words
When you use diacritic sensitivity ($diacriticSensitive: true), if the suffix stem contains the diacritic mark or marks, the $text operator matches on the exact word.
Case Insensitivity
The $text operator 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 characters from non-Latin alphabets, such as the Cyrillic alphabet. See text index for details.
Earlier versions of the
textindex are case insensitive for Latin characters without diacritic marks; i.e. for[A-z].
$caseSensitive Option
To support case sensitivity where the text index is case insensitive, specify $caseSensitive: true.
Case Sensitivity Process
If $caseSensitive: true and the text index is case insensitive, the $text operator:
First queries the
textindex for case insensitive and diacritic matches.Then, to return just the documents that match the case of the specified terms, the
$textoperation includes an additional stage to filter out the documents that do not match the specified case.
If $caseSensitive: true and if the suffix stem contains uppercase letters, the $text operator matches on the exact word.
Specifying $caseSensitive: true may impact performance.
Diacritic Insensitivity
The $text operator defaults to the diacritic insensitivity of the text index:
The version 3 text index is diacritic insensitive. That is, the index does not distinguish between characters that contain diacritical marks and their non-marked counterpart, such as
é,ê, ande.Earlier versions of the
textindex are diacritic sensitive.
$diacriticSensitive Option
To support diacritic sensitivity with the text index, specify $diacriticSensitive: true.
Text queries against earlier versions of the text index are inherently diacritic sensitive and cannot be diacritic insensitive. As such, the $diacriticSensitive option for the $text operator has no effect with earlier versions of the text index.
Diacritic Sensitivity Process
To use diacritic sensitivity ($diacriticSensitive: true) with a version 3 text index, the $text operator:
First queries the
textindex, which is diacritic insensitive.Then, to return just the documents that match the diacritic marked characters of the specified terms, the
$textoperation includes an additional stage to filter out the documents that do not match.
Specifying $diacriticSensitive: true may impact performance.
If you use $diacriticSensitive: true with an earlier version of the text index, the $text operator queries the text index, which is diacritic sensitive.
If $diacriticSensitive: true and if the suffix stem contains the diacritic mark or marks, the $text operator matches on 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 assume a collection articles that has a version 3 text index on the field 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 } ] )
$text with a Single Word
The following example specifies a $search string of coffee:
db.articles.find( { $text: { $search: "coffee" } } )
This operation returns the documents that contain the term coffee in the indexed subject field, or more precisely, the stemmed version of the word:
{ _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 of the $search Terms
If the $search string is a space-delimited string, $text performs a logical OR operation on each term and returns documents that contain any of the terms.
The following example specifies a $search string of three terms delimited by space, "bake coffee cake":
db.articles.find( { $text: { $search: "bake coffee cake" } } )
This operation returns documents that contain either bake or coffee or cake in the indexed subject field, or more precisely, the stemmed version of these words:
{ "_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 }
$text with an Exact String
To match an exact multi-word string as a single term, escape the quotes.
The following 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 }
The following example matches the strings coffee shop and Cafe con Leche. This is a logical OR of the two strings.
db.articles.find( { $text: { $search: "\'coffee shop\' \'Cafe con Leche\'" } } )
This operation returns documents that contain both the strings, including documents that contain terms from both the 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
A negated term is a term that is prefixed by a minus sign -. If you negate a term, the $text operator excludes the documents that contain those terms from the results.
The following example matches documents that contain the word coffee but do not contain the term shop, or more precisely the stemmed version of the words:
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 the optional $language field in the $text expression to specify a language that determines the list of stop words and the rules for the stemmer and tokenizer 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.
The following example specifies es, i.e. Spanish, as the language that determines the tokenization, stemming, and stop words:
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 }
The $text expression can also accept the language by name, spanish. See Text Search Languages on Self-Managed Deployments for the supported languages.
Case and Diacritic Insensitivity
The $text operator defers to the case and diacritic insensitivity of the text index. The version 3 text index is diacritic insensitive and expands its case insensitivity to include the Cyrillic alphabet as well as characters with diacritics. For details, see text Index Case Insensitivity and text Index Diacritic Insensitivity.
The following example performs a case and diacritic insensitive text query for the terms сы́рники or CAFÉS:
db.articles.find( { $text: { $search: "сы́рники CAFÉS" } } )
Using the version 3 text index, the operation matches the following documents.
{ "_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 }
With previous versions of the text index, the query would not match any document.
Case Sensitivity
To enable case sensitivity, specify $caseSensitive: true. Specifying $caseSensitive: true may impact performance.
Case Sensitivity with a Term
The following example performs a case sensitive query for the term Coffee:
db.articles.find( { $text: { $search: "Coffee", $caseSensitive: true } } )
The operation matches just the following document:
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }
Case Sensitivity with an Exact String
The following example performs a case sensitive query for the exact multi-word string Café Con Leche:
db.articles.find( { $text: { $search: "\"Café Con Leche\"", $caseSensitive: true } } )
The operation matches just the following document:
{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc", "views" : 200 }
Case Sensitivity with Negated Term
A negated term is a term that is prefixed by a minus sign -. If you negate a term, the $text operator will exclude the documents that contain those terms from the results. You can also specify case sensitivity for negated terms.
The following example performs a case sensitive query for documents that contain the word Coffee but do not contain the lower-case term shop, or more precisely the stemmed version of the words:
db.articles.find( { $text: { $search: "Coffee -shop", $caseSensitive: true } } )
The operation matches the following document:
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg" }
Diacritic Sensitivity
To enable diacritic sensitivity with a version 3 text index, specify $diacriticSensitive: true. Specifying $diacriticSensitive: true may impact performance.
Diacritic Sensitivity with a Term
The following example performs a diacritic sensitive text query on the term CAFÉ, or more precisely the stemmed version of the word:
db.articles.find( { $text: { $search: "CAFÉ", $diacriticSensitive: true } } )
The operation only matches the following document:
{ "_id" : 5, "subject" : "Café Con Leche", "author" : "abc" }
Diacritic Sensitivity with Negated Term
The $diacriticSensitive option applies also to negated terms. A negated term is a term that is prefixed by a minus sign -. If you negate a term, the $text operator will exclude the documents that contain those terms from the results.
The following example performs a diacritic sensitive text query for documents that contain the term leches but not the term cafés, or more precisely the stemmed version of the words:
db.articles.find( { $text: { $search: "leches -cafés", $diacriticSensitive: true } } )
The operation matches the following document:
{ "_id" : 8, "subject" : "Cafe con Leche", "author" : "xyz" }
Relevance Score Examples
Return the Relevance Score
The following example performs a text query for the term cake and uses the $meta operator in the projection document to append the relevance score to each matching document:
db.articles.find( { $text: { $search: "cake" } }, { score: { $meta: "textScore" } } )
The returned document includes an additional field score that contains the document's 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 the limit() method in conjunction with a sort() to return the top n matching documents.
The following example queries for the term coffee and sorts the results by the descending score, limiting the results to the top two matching documents:
db.articles.find( { $text: { $search: "coffee" } }, { score: { $meta: "textScore" } } ).sort( { score: { $meta: "textScore" } } ).limit(2)
Tip
$text with Additional Query and Sort Expressions
The following example matches documents where the author equals "xyz" and the indexed field subject contains the terms coffee or bake. The operation also specifies a sort order of ascending date, then descending relevance score:
db.articles.find( { author: "xyz", $text: { $search: "coffee bake" } }, { score: { $meta: "textScore" } } ).sort( { date: 1, score: { $meta: "textScore" } } )