Search Text
On this page
Overview
In this guide, you can learn how to use the Rust driver to run a text search. A text search allows you to efficiently query fields with string values.
Important
MongoDB text search differs from the more powerful Atlas Search feature. To learn more, see the Atlas Search documentation.
This guide includes the following sections:
Sample Data for Examples presents the sample data that is used by the text search examples
Text Index describes how to create a text index on a string-valued field
Text Search describes how to perform text searches with different search criteria
Aggregation describes how to perform text searches by using aggregation pipelines
Additional Information provides links to resources and API documentation for types and methods mentioned in this guide
Sample Data for Examples
The examples in this guide use the following Dish
struct as a model
for documents in the menu
collection:
struct Dish { name: String, description: String, }
The examples use the following sample documents that describe dishes you can order at a restaurant:
{ "name": "Shepherd’s Pie", "description": "A vegetarian take on the classic dish that uses lentils as a base. Serves 2." }, { "name": "Green Curry", "description": "A flavorful Thai curry, made vegetarian with tofu. Vegetarian and vegan friendly." }, { "name": "Herbed Branzino", "description": "Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4." }, { "name": "Kale Tabbouleh", "description": "A bright, herb-based salad. A perfect starter for vegetarians and vegans." }, { "name": "Garlic Butter Trout", "description": "Baked trout seasoned with garlic, lemon, dill, and, of course, butter. Serves 2." }
Text Index
Before you perform a text search, you must create a text index on the collection. A text index specifies the string or string array field on which you can perform text searches.
The examples in this guide perform text searches on the
description
field of documents in the menu
collection. To enable
text searches on the description
field, create a text index as shown
in the following code:
let index = IndexModel::builder() .keys(doc! { "description": "text" }) .build(); let idx_res = my_coll.create_index(index).await?;
Text Search
A text search retrieves documents that contain a specified term or phrase in the value of the indexed field. A term is a sequence of characters that excludes whitespace characters. A phrase is a sequence of terms with any number of whitespace characters.
To perform a text search, include the $text
evaluation query operator,
followed by the $search
field in your query filter. The $text
operator
specifies that you are performing a text search on the text-indexed
fields. The $search
field specifies the term or phrase to search for
in the text-indexed field or fields.
Query filters for text searches use the following format:
let filter = doc! { "$text": { "$search": "<search term or phrase>" } };
Search for a Term
To search for a term, specify the term as a string in your query filter. To search for multiple terms, separate each term with a space.
Note
When searching for multiple terms, the find()
method returns any
document in which the text-indexed field or fields contain at least
one of the terms.
For example, if your search terms are "one two
three"
, MongoDB returns documents in which the indexed field
contains "one"
, "two"
, "three"
, or more than one of these terms.
Example
The following example performs a search for documents in which the
description
field contains the term "herb"
:
let filter = doc! { "$text": { "$search": "herb" } }; let mut cursor = my_coll.find(filter).await?; while let Some(doc) = cursor.try_next().await? { println!("{:?}", doc); }
Dish { name: "Kale Tabbouleh", description: "A bright, herb-based salad. A perfect starter for vegetarians and vegans." } Dish { name: "Herbed Branzino", description: "Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4." }
Tip
Even though the search term is "herb"
, the text search also matches
documents in which the description
field contains "herbs"
.
This is because a MongoDB text index uses suffix stemming to match
similar words. To learn more about how MongoDB matches terms, see
Index Entries in the
Server manual.
Search for a Phrase
To search for a phrase, specify the phrase with escaped quotes in your query filter:
let filter = doc! { "$text": { "$search": "\"<some phrase>\"" } };
If you don't add escaped quotes around the phrase, the search performs a term search.
Example
The following example performs a search for documents in which the
description
field contains the phrase "serves 2"
:
let filter = doc! { "$text": { "$search": "\"serves 2\"" } }; let mut cursor = my_coll.find(filter).await?; while let Some(doc) = cursor.try_next().await? { println!("{:?}", doc); }
Dish { name: "Shepherd’s Pie", description: "A vegetarian take on the classic dish that uses lentils as a base. Serves 2." } Dish { name: "Garlic Butter Trout", description: "Baked trout seasoned with garlic, lemon, dill, and, of course, butter. Serves 2." }
Exclude Terms from Search
To specify a term or phrase you want to exclude from your text search, prefix it with a minus sign in your query filter:
let filter = doc! { "$text": { "$search": "<term> -<excluded term>" } };
Important
You must search for at least one term or phrase to exclude other terms from your search. If you only exclude terms, the search doesn't return any documents.
Example
The following example performs a search for documents in which the
description
field contains the term "vegan"
, but does not
contain the term "tofu"
:
let filter = doc! { "$text": { "$search": "vegan -tofu" } }; let mut cursor = my_coll.find(filter).await?; while let Some(doc) = cursor.try_next().await? { println!("{:?}", doc); }
Dish { name: "Kale Tabbouleh", description: "A bright, herb-based salad. A perfect starter for vegetarians and vegans." }
Sort by Relevance
A text search assigns a numerical text score to indicate how closely
each result matches the string in your query filter. A higher text score
indicates that the result is more relevant to your query. To reveal the text
score in your output, use a projection to retrieve the textScore
field from the metadata. You can sort the text score in descending order
by specifying a sort on the textScore
metadata field.
Example
This example performs the following actions:
Performs a search for documents in which the
description
field contains the term"vegetarian"
Sorts the results in descending order on text score
Includes only the
name
andscore
fields in the output
let filter = doc! { "$text": { "$search": "vegetarian" } }; let sort = doc! { "score": { "$meta": "textScore" } }; let projection = doc! { "_id": 0, "name": 1, "score": { "$meta": "textScore" } }; let doc_coll: Collection<Document> = my_coll.clone_with_type(); let mut cursor = doc_coll.find(filter) .sort(sort) .projection(projection) .await?; while let Some(doc) = cursor.try_next().await? { println!("{:?}", doc); }
Document({"name": String("Green Curry"), "score": Double(0.9166666666666667)}) Document({"name": String("Kale Tabbouleh"), "score": Double(0.5625)}) Document({"name": String("Shepherd’s Pie"), "score": Double(0.5555555555555556)})
Aggregation
You can include the $text
evaluation query operator in a
$match aggregation
stage to perform a text search in an aggregation pipeline.
The following sections demonstrate how to perform text searches by using
aggregation pipelines instead of the find()
method.
Match a Search Term
The following example uses an aggregation to perform a search for
documents in which the description
field contains the term
"herb"
:
let match_stage = doc! { "$match": { "$text": { "$search": "herb" } } }; let mut cursor = my_coll.aggregate([match_stage]).await?; while let Some(doc) = cursor.try_next().await? { println!("{:?}", doc); }
Document({"_id": ObjectId("..."), "name": String("Kale Tabbouleh"), "description": String("A bright, herb-based salad. A perfect starter for vegetarians and vegans.")}) Document({"_id": ObjectId("..."), "name": String("Herbed Branzino"), "description": String("Grilled whole fish stuffed with herbs and pomegranate seeds. Serves 3-4.")})
Sort by Relevance
This example uses an aggregation to perform the following actions:
Performs a search for documents in which the
description
field contains the term"vegetarian"
Sorts the results in descending order on text score
Includes only the
name
andscore
fields in the output
let match_stage = doc! { "$match": { "$text": { "$search": "vegetarian" } } }; let sort_stage = doc! { "$sort": { "score": { "$meta": "textScore" } } }; let proj_stage = doc! { "$project": { "_id": 0, "name": 1, "score": { "$meta": "textScore" } } }; let pipeline = [match_stage, sort_stage, proj_stage]; let mut cursor = my_coll.aggregate(pipeline).await?; while let Some(doc) = cursor.try_next().await? { println!("{:?}", doc); }
Document({"name": String("Green Curry"), "score": Double(0.9166666666666667)}) Document({"name": String("Kale Tabbouleh"), "score": Double(0.5625)}) Document({"name": String("Shepherd’s Pie"), "score": Double(0.5555555555555556)})
Additional Information
For a runnable example that uses the find()
method, see the
Find Multiple Documents usage example.
To learn more about the operations in this guide, see the following documentation:
Text Indexes in the Server manual
$text in the Server manual
$meta in the Server manual
API Documentation
To learn more about the methods and types mentioned in this guide, see the following API documentation: