Docs Menu
Docs Home
/ / /
Rust Driver
/ / /

Search Text

On this page

  • Overview
  • Sample Data for Examples
  • Text Index
  • Text Search
  • Search for a Term
  • Search for a Phrase
  • Exclude Terms from Search
  • Sort by Relevance
  • Aggregation
  • Match a Search Term
  • Sort by Relevance
  • Additional Information
  • API Documentation

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

The examples in this guide use the following Dish struct as a model for documents in the menu collection:

#[derive(Serialize, Deserialize, Debug)]
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." }

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?;

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

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.

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.

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.

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

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.

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

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.

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 and score 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)})

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.

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

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 and score 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)})

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:

To learn more about the methods and types mentioned in this guide, see the following API documentation:

Back

Open Change Streams