$text (Self-Managed Deployments)
On this page
Note
This page describes text query capabilities for self-managed (non-Atlas) deployments. For data hosted on MongoDB Atlas, MongoDB offers an improved full-text query solution, Atlas Search.
This page describes the $text
operator for self-managed deployments.
Definition
$text
$text
performs 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 |
---|---|---|
$search | string | |
$language | 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 |
$caseSensitive | boolean | Optional. A boolean flag to enable or disable case sensitivity.
Defaults to For more information, see Case Insensitivity. |
$diacriticSensitive | 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
$text
expression.$text
cannot appear in$nor
expressions.$text
cannot appear in$elemMatch
query expressions or$elemMatch
projection expressions.To use
$text
in an$or
expression, all clauses in the$or
array must be indexed.If a query includes a
$text
expression, you cannot usehint()
to specify which index to use for the query.You cannot specify the
$natural
sort order if the query includes a$text
expression.You cannot combine the
$text
expression, which requires a special text index, with a query operator that requires a different type of special index. For example you cannot combine$text
expression with the$near
operator.Views do not support
$text
.$text
is unsupported for creating indexes using the Stable API V1.
If using the $text
operator in aggregation, the following
restrictions also apply.
The
$match
stage that includes a$text
must be the first stage in the pipeline.A
$text
operator can only occur once in the stage.The
$text
operator expression cannot appear in$or
or$not
expressions.$text
, by default, does not return the matching documents in order of matching scores. To sort by descending score, use the$meta
aggregation expression in the$sort
stage.
$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 a phrase.
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.
Phrases
To match on a phrase, as opposed to individual terms, enclose the
phrase in escaped double quotes (\"
), as in:
"\"ssl certificate\""
If the $search
string of a $text
operation includes a phrase and
individual terms, $text
only matches the documents that include the
phrase.
For example, passed a $search
string:
"\"ssl certificate\" authority key"
The $text
operator returns documents that include the phrase "ssl
certificate"
.
Note
You cannot use the $text
operator with multiple phrases.
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,
$text
does not match any documents.A hyphenated word, such as
pre-market
, is not a negation. If used in a hyphenated word, the$text
operator treats the hyphen-minus (-
) as a delimiter. To negate the wordmarket
in this instance, include a space betweenpre
and-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
text
index 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
text
index for case insensitive and diacritic matches.Then, to return just the documents that match the case of the specified terms, the
$text
operation 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
text
index 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
text
index, which is diacritic insensitive.Then, to return just the documents that match the diacritic marked characters of the specified terms, the
$text
operation 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 a Phrase
To match the exact phrase as a single term, escape the quotes.
The following example matches the phrase coffee shop
:
db.articles.find( { $text: { $search: "\"coffee shop\"" } } )
This operation returns documents that contain the phrase coffee shop
:
{ "_id" : 2, "subject" : "Coffee Shopping", "author" : "efg", "views" : 5 }
The following example matches the phrases coffee shop
and Cafe
con Leche
. This is a logical OR of the two phrases.
db.articles.find( { $text: { $search: "\'coffee shop\' \'Cafe con Leche\'" } } )
This operation returns documents that contain both the phrases, including documents that contain terms from both the phrases:
[ { _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 a Phrase
The following example performs a case sensitive query for the phrase
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 }
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 namedscore
for the expression and thesort()
uses the field namedignoredName
.db.articles.find( { $text: { $search: "cake" } } , { score: { $meta: "textScore" } } ).sort( { ignoredName: { $meta: "textScore" } } )
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)
$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" } } )