Docs Menu

Docs HomeGo

Search Text

On this page

  • Overview
  • Sample Data
  • Text Index
  • Text Search
  • Search by a Term
  • Search by a Phrase
  • Search with Terms Excluded
  • Sort by Relevance
  • Aggregation
  • Term Search Example
  • Text Score Example
  • Additional Information
  • API Documentation

In this guide, you can learn how to run a text search.

Important

MongoDB text search is different than Atlas Search.

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.

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)

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

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.

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

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.

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

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.

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

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.

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 and score 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.

You can also include the $text evaluation query operator in the $match stage to perform a text search in an aggregation pipeline.

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

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 and score 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.

To learn more about the operations mentioned, see the following guides:

To learn more about any of the methods or types discussed in this guide, see the following API Documentation:

←  Specify Which Fields to ReturnWatch for Changes →
Give Feedback
© 2022 MongoDB, Inc.

About

  • Careers
  • Investor Relations
  • Legal Notices
  • Privacy Notices
  • Security Information
  • Trust Center
© 2022 MongoDB, Inc.