Search Text
On this page
Overview
In this guide, you can learn how to run a text search.
Important
MongoDB text search is different than Atlas Search.
Sample Data
To run the examples in this guide, load the sample data into the
marvel.movies
collection with the following
snippet:
coll := client.Database("marvel").Collection("movies") docs := []interface{}{ bson.D{{"title", "Captain America: Civil War"}, {"year", 2016}}, bson.D{{"title", "The Avengers"}, {"year", 2012}}, bson.D{{"title", "Captain America: The Winter Soldier"}, {"year", 2014}}, bson.D{{"title", "Avengers: Infinity War"}, {"year", 2018}}, bson.D{{"title", "Captain America: The First Avenger"}, {"year", 2011}}, } result, err := coll.InsertMany(context.TODO(), docs) if err != nil { panic(err) } fmt.Printf("Number of documents inserted: %d\n", len(result.InsertedIDs))
Tip
Non-existent Databases and Collections
If the necessary database and collection don't exist when you perform a write operation, the server implicitly creates them.
Each document contains the name and release year of the Marvel movie
that corresponds to the title
and year
fields.
Note
Each example truncates the ObjectID
value because the driver
generates them uniquely.
Text Index
You must create a text index before running a text search. A text index specifies the string or string array field on which to run a text search.
The examples in the following sections run text searches on the
title
field in the movies
collection. To enable text searches on
the title
field, create a text index with the following snippet:
model := mongo.IndexModel{Keys: bson.D{{"title", "text"}}} name, err := coll.Indexes().CreateOne(context.TODO(), model) if err != nil { panic(err) } fmt.Println("Name of Index Created: " + name)
Text Search
A text search retrieves documents that contain a term or a phrase in the text indexed fields. 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, use the $text
evaluation query operator,
followed by the $search
field in your query filter. The $text
operator
performs a text search on the text indexed fields. The $search
field
specifies the text to search in the text indexed fields.
Query filters for text searches use the following format:
filter := bson.D{{"$text", bson.D{{"$search", "<text to search>"}}}}
Search by 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 spaces in the string.
Note
When searching for multiple terms, the Find()
method returns
documents with at least one of the terms in text indexed fields.
Example
The following example runs a text search for titles that contain the term "War":
filter := bson.D{{"$text", bson.D{{"$search", "War"}}}} cursor, err := coll.Find(context.TODO(), filter) if err != nil { panic(err) } var results []bson.D if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { fmt.Println(result) }
Search by a Phrase
To search for a phrase, specify the phrase with escaped quotes as a
string in your query filter. If you don't add escaped quotes around the
phrase, the Find()
method runs a term search.
Tip
Escaped quotes are a backslash character followed by a double quote character.
Example
The following example runs a text search for titles that contain the phrase "Infinity War":
filter := bson.D{{"$text", bson.D{{"$search", "\"Infinity War\""}}}} cursor, err := coll.Find(context.TODO(), filter) if err != nil { panic(err) } var results []bson.D if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { fmt.Println(result) }
Search with Terms Excluded
For each term or phrase you want to exclude from your text search, specify the term or phrase prefixed with a minus sign as a string in your query filter.
Important
You must search for at least one term if you want to exclude
terms from your search. If you don't search for any terms, the
Find()
method doesn't return any documents.
Example
The following example runs a text search for titles that contain the term "Avenger", but does not contain the phrase "Captain America":
filter := bson.D{{"$text", bson.D{{"$search", "Avenger -\"Captain America\""}}}} cursor, err := coll.Find(context.TODO(), filter) if err != nil { panic(err) } var results []bson.D if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { fmt.Println(result) }
Sort by Relevance
A text search assigns a numerical text score to indicate how closely
each result matches the string in your query filter. To reveal the text
score in your output, use a projection to retrieve the textScore
metadata. You can sort the text score in descending order by specifying
a sort on the textScore
metadata.
Example
The following example performs the following actions:
Runs a text search for titles that contain the term "Avenger"
Sorts the results in descending order based on their text score
Includes the
title
andscore
fields from the results
filter := bson.D{{"$text", bson.D{{"$search", "Avenger"}}}} sort := bson.D{{"score", bson.D{{"$meta", "textScore"}}}} projection := bson.D{{"title", 1}, {"score", bson.D{{"$meta", "textScore"}}}, {"_id", 0}} opts := options.Find().SetSort(sort).SetProjection(projection) cursor, err := coll.Find(context.TODO(), filter, opts) if err != nil { panic(err) } var results []bson.D if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { fmt.Println(result) }
Tip
Although the search term was "Avenger", the method also matches titles containing "Avengers" because a MongoDB text index uses suffix stemming to match similar words. To learn more about how MongoDB matches terms, see Index Entries.
Aggregation
You can also include the $text
evaluation query operator in the
$match stage to
perform a text search in an aggregation pipeline.
Term Search Example
The following example runs a text search for titles that contain the term "Winter":
matchStage := bson.D{{"$match", bson.D{{"$text", bson.D{{"$search", "Winter"}}}}}} cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{matchStage}) if err != nil { panic(err) } var results []bson.D if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { fmt.Println(result) }
Text Score Example
The following example performs the following actions:
Runs a text search for titles that contain the term "Avenger"
Sorts the results in descending order based on their text score
Includes the
title
andscore
fields from the results
matchStage := bson.D{{"$match", bson.D{{"$text", bson.D{{"$search", "Avenger"}}}}}} sortStage := bson.D{{"$sort", bson.D{{"score", bson.D{{ "$meta", "textScore" }}}}}} projectStage := bson.D{{"$project", bson.D{{"title", 1}, {"score", bson.D{{ "$meta", "textScore" }}}, {"_id", 0}}}} cursor, err := coll.Aggregate(context.TODO(), mongo.Pipeline{matchStage, sortStage, projectStage}) if err != nil { panic(err) } var results []bson.D if err = cursor.All(context.TODO(), &results); err != nil { panic(err) } for _, result := range results { fmt.Println(result) }
Tip
Although the search term was "Avenger", the method also matches titles containing "Avengers" because a MongoDB text index uses suffix stemming to match similar words. To learn more about how MongoDB matches terms, see Index Entries.
Additional Information
To learn more about the operations mentioned, see the following guides:
API Documentation
To learn more about any of the methods or types discussed in this guide, see the following API Documentation: