Docs Menu
Docs Home
/ /

$text (Self-Managed Deployments)

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.

$text

$text performs a text query on fields indexed with a text index.

You can use $text for deployments hosted in the following environments:

  • MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud

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

$search

string

A string of terms that MongoDB parses and uses to query the text index. MongoDB performs a logical OR query on the terms unless you specify an exact string. See Behavior for details.

$language

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 default_language value of none, the text index parses through each word in the field, including stop words, and ignores suffix stemming.

$caseSensitive

boolean

Optional. Enables case sensitivity. Defaults to false. See Case Insensitivity.

$diacriticSensitive

boolean

Optional. Enables diacritic sensitivity for version 3 text indexes. Defaults to false. Earlier text index versions are always diacritic sensitive. See Diacritic Insensitivity.

By default, $text does not sort results by score. See Text Score for details on score sorting.

  • A query can specify only one $text expression.

  • $text cannot appear in $nor expressions.

  • $text cannot appear in $elemMatch query or projection expressions.

  • All $or clauses must be indexed to use $text.

  • If a query includes a $text expression, you cannot use hint() to specify which index to use for the query.

  • Queries with $text cannot use $natural sort.

  • 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.

  • Stable API V1 does not support $text for index creation.

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.

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.

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"

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-market are not negations. MongoDB treats the hyphen as a delimiter. To negate market, use pre -market.

MongoDB applies all negations to the operation with logical AND.

MongoDB ignores language-specific stop words such as the and and in English.

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.

With case sensitivity enabled ($caseSensitive: true), if the suffix stem contains uppercase letters, $text matches the exact word.

With diacritic sensitivity enabled ($diacriticSensitive: true), if the suffix stem contains diacritic marks, $text matches the exact word.

$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]).

Specify $caseSensitive: true to enable case sensitivity when the text index is case insensitive.

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.

$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.

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.

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.

Tip

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.

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 }
] )

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 }

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 }

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 }
]

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 }

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.

$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.

Enable case sensitivity with $caseSensitive: true. This may reduce performance.

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 }

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 }

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" }

Enable diacritic sensitivity with version 3 text indexes using $diacriticSensitive: true. This may reduce performance.

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" }

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" }

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 }
  • 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" } } )

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)

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" } } )

Back

Text Search Operators (Self-Managed Deployments)

On this page