Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs Menu
Docs Home
/ /

$text (query predicate operator)

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.

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

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 allowDiskUse is true, the stage spills intermediate results to disk.

  • If allowDiskUse is false, 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.

The examples on this page use data from the sample_mflix sample dataset. For details on how to load this dataset into your self-managed MongoDB deployment, see Load the sample dataset. If you made any modifications to the sample databases, you may need to drop and recreate the databases to run the examples on this page.

The examples assume a version 3 text index on the title and fullplot fields:

db.movies.createIndex( { title: "text", fullplot: "text" } )

This example specifies baseball in the $search string. The query returns documents containing the stemmed version of baseball in the indexed title or fullplot fields:

db.movies.find(
{ $text: { $search: "baseball" }, runtime: { $gt: 1000 } },
{ _id: 0, title: 1, year: 1, runtime: 1 }
)
[ { title: 'Baseball', year: 1994, runtime: 1140 } ]

A space-delimited $search string performs a logical OR on each term. MongoDB returns documents containing any of the terms.

This example specifies two space-delimited terms. The query returns documents containing the stemmed versions of baseball or colorado in the indexed title or fullplot fields:

db.movies.find(
{ $text: { $search: "baseball colorado" },
runtime: { $gt: 1000 } },
{ _id: 0, title: 1, year: 1, runtime: 1, fullplot: 1 }
)
[
{
runtime: 1140,
title: 'Baseball',
fullplot: 'Ken Burns relates the history of baseball in a fashion similar to that of his Civil War mini series. Old-time photos and illustrations depict the games early years, while newsreels and video clips highlight more recent developments. Players and participants speak in their own words, and sports writers and broadcasters offer commentary on the sport and events they witnessed.',
year: 1994
},
{
runtime: 1256,
title: 'Centennial',
fullplot: 'This is the story of the evolution of the town Centennial, Colorado. It follows the paths of dozens of people who come to the area for many reasons: money, freedom, or crime. It also shows the bigoted treatment of the Native Indians by the advancing US colonists. It is topped off with a murder mystery that takes 100 years to solve.',
year: 1978
}
]

Escape the quotes to match an exact multi-word string.

This example matches the exact phrase ken burns:

db.movies.find(
{ $text: { $search: "\"ken burns\"" },
runtime: { $gt: 1000 } },
{ _id: 0, title: 1, year: 1, runtime: 1, fullplot: 1 }
)
[
{
runtime: 1140,
title: 'Baseball',
fullplot: 'Ken Burns relates the history of baseball in a fashion similar to that of his Civil War mini series. Old-time photos and illustrations depict the games early years, while newsreels and video clips highlight more recent developments. Players and participants speak in their own words, and sports writers and broadcasters offer commentary on the sport and events they witnessed.',
year: 1994
}
]

This example performs a logical OR of two exact strings:

db.movies.find(
{ $text: { $search: "\'ken burns\' \'centennial\'" },
runtime: { $gt: 1000 } },
{ _id: 0, title: 1, year: 1, runtime: 1, fullplot: 1 }
)
[
{
runtime: 1140,
title: 'Baseball',
fullplot: 'Ken Burns relates the history of baseball in a fashion similar to that of his Civil War mini series. Old-time photos and illustrations depict the games early years, while newsreels and video clips highlight more recent developments. Players and participants speak in their own words, and sports writers and broadcasters offer commentary on the sport and events they witnessed.',
year: 1994
},
{
runtime: 1256,
title: 'Centennial',
fullplot: 'This is the story of the evolution of the town Centennial, Colorado. It follows the paths of dozens of people who come to the area for many reasons: money, freedom, or crime. It also shows the bigoted treatment of the Native Indians by the advancing US colonists. It is topped off with a murder mystery that takes 100 years to solve.',
year: 1978
}
]

Prefix a term with - to exclude documents containing that term.

This example matches documents containing baseball or colorado but not sport (stemmed versions):

db.movies.find(
{ $text: { $search: "baseball colorado -sport" },
runtime: { $gt: 1000 } },
{ _id: 0, title: 1, year: 1, runtime: 1 }
)
[ { title: 'Centennial', year: 1978, runtime: 1256 } ]

This example queries for baseball and uses $meta to append the relevance score to each matching document. The returned document includes a score field with the relevance score:

db.movies.find(
{ $text: { $search: "baseball" }, runtime: { $gt: 1000 } },
{ _id: 0, title: 1, year: 1,
score: { $meta: "textScore" } }
)
[
{
title: 'Baseball',
year: 1994,
score: ...
}
]

Use limit() with sort() to return the top matching documents.

This example queries for baseball or colorado, sorts by descending score, and limits results to the top two documents:

db.movies.find(
{ $text: { $search: "baseball colorado" },
runtime: { $gt: 1000 } },
{ _id: 0, title: 1, year: 1,
score: { $meta: "textScore" } }
).sort( { score: { $meta: "textScore" } } ).limit(2)
[
{ title: 'Baseball', year: 1994, score: ... },
{ title: 'Centennial', year: 1978, score: ... }
]

This example matches documents where runtime is greater than 1000 and the indexed fields contain baseball or colorado. It sorts by ascending year, then descending relevance score:

db.movies.find(
{ runtime: { $gt: 1000 },
$text: { $search: "baseball colorado" } },
{ _id: 0, title: 1, year: 1,
score: { $meta: "textScore" } }
).sort( { year: 1, score: { $meta: "textScore" } } )
[
{ title: 'Centennial', year: 1978, score: ... },
{ title: 'Baseball', year: 1994, score: ... }
]

The rest of the examples on this page use an articles collection with a version 3 text index on subject:

db.articles.createIndex( { subject: "text" } )

The collection contains 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 }
] )

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" } }
)
[
{ _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.

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

$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. Using version 3 text indexes, the query matches documents containing the stemmed versions of the search terms:

db.articles.find( { $text: { $search: "сы́рники CAFÉS" } } )
[
{ _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 } }
)
[ { _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 }
} )
[ { _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 } }
)
[ { _id: 2, subject: 'Coffee Shopping', author: 'efg', views: 5 } ]

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 } }
)
[ { _id: 5, subject: 'Café Con Leche', author: 'abc', views: 200 } ]

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 } }
)
[ { _id: 8, subject: 'Cafe con Leche', author: 'xyz', views: 10 } ]

Back

$text Query Operators

On this page