Overview
In this guide you can learn how to use the Search builder to build a $search
aggregation pipeline stage with the MongoDB .NET/C# Driver.
To learn more about the $search pipeline stage, see $search.
Note
Atlas and Community Edition Version Requirements
The $search aggregation-pipeline operator is available only for
collections hosted on MongoDB Atlas clusters running
MongoDB v4.2 or later, or on MongoDB Community Edition clusters running MongoDB v8.2 or later. Collections
must be covered by a MongoDB Search index. To learn more about
the required setup and the functionality of this operator, see the
MongoDB Search documentation.
Sample Data
The examples in this guide use the movies collection from the
sample_mflix database. Documents in this collection contain information
about films, including their title, plot, genre, and ratings. The following
Movie class models the documents in this collection:
[] public class Movie { [] public ObjectId Id { get; set; } public string Title { get; set; } = null!; public string Plot { get; set; } = null!; public string[] Genres { get; set; } = null!; public int Year { get; set; } public string Rated { get; set; } = null!; public Imdb Imdb { get; set; } = null!; [] public float[] PlotEmbedding { get; set; } = null!; public double Score { get; set; } [] public string PaginationToken { get; set; } = null!; }
The Movie class references the following Imdb class, which
models the nested imdb field in each document:
[] public class Imdb { public double Rating { get; set; } public int Votes { get; set; } public int Id { get; set; } }
Note
Camel-Case Field Names in Sample Data
The documents in the movies collection use the camel-case naming
convention. The examples in this guide use a ConventionPack
to deserialize the fields in the collection into Pascal case and map them to
the properties in the Movie class.
To learn more about custom serialization, see Custom Serialization.
Some examples in this guide use additional collections and model classes, which the relevant sections introduce. All collections are from the sample datasets provided by Atlas. See Get Started with the .NET/C# Driver to learn how to create a free MongoDB cluster and load this sample data.
Note
Inconsistent Field Types in Sample Data
Some documents in the movies collection store the
imdb.rating and imdb.votes fields as strings instead of
numbers. If you define these fields as double or int in
your model class, the driver throws a FormatException when
deserializing those documents.
To handle documents with mixed field types, implement a custom
serializer that accepts multiple BSON types and apply it with the
[BsonSerializer] attribute on the affected properties:
[] public class Imdb { [] public double Rating { get; set; } [] public int Votes { get; set; } public int Id { get; set; } }
To learn how to implement a custom serializer such as
FlexibleDoubleSerializer, see
Custom Serializers.
Create a MongoDB Search Index
Before you can perform a search on an Atlas collection, you must first create a MongoDB Search index on the collection. A MongoDB Search index is a data structure that categorizes data in a searchable format.
To learn how to create a MongoDB Search Index see the Create a MongoDB Search Index guide.
MongoDB Search Operators and Collectors
The Search class contains methods you can use to perform $search
operations. For a full list of available $search operators and collectors, see the Operators and Collectors Atlas guide.
Autocomplete
Use the Autocomplete() method to search for a word or phrase that contains a
sequence of characters from an incomplete input string.
The following example performs an autocomplete query on the title
field for text that starts with the string "Gravity":
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Autocomplete(m => m.Title, "Gravity"), indexName: "movietitles") .ToList();
... { "_id" : ObjectId("..."), "title" : "Gravity", "plot" : "...", "genres" : ["Drama", "Sci-Fi", "Thriller"], "year" : 2013, "rated" : "PG-13", "imdb" : { "rating" : 7.7, "votes" : "...", "id" : "..." } } ...
To learn more about the autocomplete operator, see the autocomplete
Atlas guide.
Note
Index for Autocomplete Queries
You must create a MongoDB Search index that supports autocompletion to successfully perform autocomplete queries. To learn more, see How to Index Fields for Autocompletion in the Atlas documentation.
After you create the MongoDB Search index, you must pass the index name to
the Autocomplete() method, as shown in the preceding example.
Compound
Use the Compound() method to combine two or more operators into a single
search.
The following example searches the movies collection for any documents
that match all the following criteria:
The
imdb.ratingfield exists on the documentThe
ratedfield value is not"G"The
yearfield has a value greater than 2000
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Compound() .Must(Builders<Movie>.Search.Exists(m => m.Imdb.Rating)) .MustNot(Builders<Movie>.Search.Equals(m => m.Rated, "G")) .Must(Builders<Movie>.Search.Range(m => m.Year, SearchRangeBuilder.Gt(2000)))) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Dark Knight", "plot" : "...", "genres" : ["Action", "Crime", "Drama"], "year" : 2008, "rated" : "PG-13", "imdb" : { "rating" : 9.0, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Inception", "plot" : "...", "genres" : ["Action", "Adventure", "Sci-Fi"], "year" : 2010, "rated" : "PG-13", "imdb" : { "rating" : 8.8, "votes" : "...", "id" : "..." } } ...
To learn more about the compound operator, see the compound
Atlas guide.
EmbeddedDocument
Use the EmbeddedDocument() method to perform search operations on documents
within a field's array value.
Note
Embedded Document Index Required
To search on embedded documents, you must create an
embeddedDocument index on the array field.
To learn how to define an embeddedDocument index, see
Define the Index for the embeddedDocument Type
in the Atlas documentation.
This example uses the restaurants collection from the
sample_restaurants database. The following classes model the
documents in that collection:
[] public class Restaurant { [] public ObjectId Id { get; set; } public string Name { get; set; } = null!; public string Cuisine { get; set; } = null!; public string Borough { get; set; } = null!; public List<GradeEntry> Grades { get; set; } = null!; }
[] public class GradeEntry { public string Grade { get; set; } = null!; public int? Score { get; set; } }
The following example searches that collection for any restaurants whose
grades array contains an entry with a grade field value of
"A":
var result = restaurantsCollection.Aggregate() .Search(Builders<Restaurant>.Search.EmbeddedDocument( r => r.Grades, Builders<GradeEntry>.Search.Equals(g => g.Grade, "A") ), indexName: "restaurantsembedded").ToList();
... { "_id" : ObjectId("..."), "name" : "Riviera Caterer", "cuisine" : "American", "borough" : "Brooklyn", "grades" : [{ "grade" : "A", "score" : 5 }, { "grade" : "B", "score" : 23 }] } ...
To learn more about the embeddedDocument operator, see the
embeddedDocument Atlas guide.
Equals
Use the Equals() method to check whether a field matches a specified
value.
The following example searches the movies collection for any documents in
which the value of the year field is 2000:
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Equals(m => m.Year, 2000)) .ToList();
... { "_id" : ObjectId("..."), "title" : "Gladiator", "plot" : "...", "genres" : ["Action", "Adventure", "Drama"], "year" : 2000, "rated" : "R", "imdb" : { "rating" : 8.5, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Cast Away", "plot" : "...", "genres" : ["Adventure", "Drama", "Romance"], "year" : 2000, "rated" : "PG-13", "imdb" : { "rating" : 7.8, "votes" : "...", "id" : "..." } } ...
To learn more about the equals operator, see the equals
Atlas guide.
Exists
Use the Exists() method to search for documents in which a specified indexed
field name exists. If the specified field exists but isn't indexed, the
document isn't included with the result set.
The following example searches the movies collection for any documents in
which the imdb.rating field exists. The search returns all documents in
which the imdb.rating field is present:
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Exists(m => m.Imdb.Rating)) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Godfather", "plot" : "...", "genres" : ["Crime", "Drama"], "year" : 1972, "rated" : "R", "imdb" : { "rating" : 9.2, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "The Shawshank Redemption", "plot" : "...", "genres" : ["Drama"], "year" : 1994, "rated" : "R", "imdb" : { "rating" : 9.3, "votes" : "...", "id" : "..." } } ...
To learn more about the exists operator, see the exists
Atlas guide.
Facet
Use the Facet() method to group results by values or ranges in the specified faceted fields
and return the count for each of those groups.
You can use the Facet() method with both the $search and $searchMeta stages. MongoDB recommends using
facet with the $searchMeta stage to retrieve metadata results only for the query.
To retrieve metadata results and query results using the $search stage, you must use the
$$SEARCH_META aggregation variable. To learn more about this variable, see the SEARCH_META Aggregation Variable Atlas guide.
The following limitations apply:
You can run facet queries on a single field only. You can't run facet queries on groups of fields.
You can run facet queries over sharded collections on clusters running MongoDB v6.0 only.
The following example searches the movies collection for any documents in
which the year field has a value greater than or equal to 2000. The query uses the Facet() method to process the input documents, with a maximum number of 100 facet categories to return in the results based on the genres field. The query returns the number of distinct genre categories found:
var result = moviesCollection.Aggregate() .SearchMeta( Builders<Movie>.Search.Facet( Builders<Movie>.Search.Range(m => m.Year, SearchRangeBuilder.Gte(2000)), Builders<Movie>.SearchFacet.String("genres", m => m.Genres, 100)), indexName: "moviesfacetsearch") .Single() .Facet["genres"].Buckets.Count();
23
To learn more about the facet collector, see the facet
Atlas guide.
GeoShape
Use the GeoShape() method to search for documents in relation to a given
geometry. When specifying the coordinates to search, longitude must be specified
first, followed by latitude. Longitude values can be between -180 and
180, inclusive. Latitude values can be between -90 and 90,
inclusive.
Note
MongoDB Search does not support the following:
Non-default coordinate reference system (CRS)
Planar XY coordinate system (2 dimensional)
Coordinate pairs Point notation (pointFieldName: [12, 34])
This example uses the theaters collection from the sample_mflix
database. The following classes model the documents in that collection:
[] public class Theater { [] public ObjectId Id { get; set; } public int TheaterId { get; set; } public TheaterLocation Location { get; set; } = null!; }
[] public class TheaterLocation { [] public GeoJsonPoint<GeoJson2DGeographicCoordinates> Geo { get; set; } = null!; }
The following example searches that collection for all documents in which
the coordinates in the location.geo field intersect with a specified
polygon in the Minneapolis, MN area:
GeoJsonPolygon<GeoJson2DGeographicCoordinates> searchArea = new(new(new(new GeoJson2DGeographicCoordinates[] { new(-93.5, 44.7), new(-93.5, 45.0), new(-93.0, 45.0), new(-93.0, 44.7), new(-93.5, 44.7), }))); var result = theatersCollection.Aggregate() .Search(Builders<Theater>.Search.GeoShape( t => t.Location.Geo, GeoShapeRelation.Intersects, searchArea), indexName: "theatersgeo") .ToList();
... { "_id" : ObjectId("..."), "theaterId" : 1000, "location" : { "geo" : { "type" : "Point", "coordinates" : [-93.24565, 44.85466] } } } ...
To learn more about the geoShape operator, see the geoShape
Atlas guide.
GeoWithin
Use the GeoWithin() method to search for documents in which the coordinates of
their specified GeoJSON field are within a given
geometry. You can search for points that are within a:
Circle
Bounding box
Polygon
When specifying the coordinates to search, longitude must be specified
first, followed by latitude. Longitude values can be between -180 and
180, inclusive. Latitude values can be between -90 and 90,
inclusive.
Note
MongoDB Search does not support the following:
Non-default coordinate reference system (CRS)
Planar XY coordinate system (2 dimensional)
Coordinate pairs Point notation (pointFieldName: [12, 34])
The following example searches the theaters collection for all documents
in which the coordinates in the location.geo field fall within a
specified polygon:
GeoJsonPolygon<GeoJson2DGeographicCoordinates> searchArea = new(new(new(new GeoJson2DGeographicCoordinates[] { new(-94.0, 44.5), new(-94.0, 45.2), new(-92.5, 45.2), new(-92.5, 44.5), new(-94.0, 44.5), }))); var result = theatersCollection.Aggregate() .Search(Builders<Theater>.Search.GeoWithin(t => t.Location.Geo, searchArea), indexName: "theatersgeo") .ToList();
... { "_id" : ObjectId("..."), "theaterId" : 1000, "location" : { "geo" : { "type" : "Point", "coordinates" : [-93.24565, 44.85466] } } } ...
To learn more about the geoWithin operator, see the geoWithin
Atlas guide.
In
Use the In() method to search for documents with field values that match a list
of specified values.
The following example searches the movies collection for documents that have a
genres array containing either "Action" or "Comedy":
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.In(m => m.Genres, new[] { "Action", "Comedy" })) .ToList();
... { "_id" : ObjectId("..."), "title" : "Home Alone", "plot" : "...", "genres" : ["Comedy", "Family"], "year" : 1990, "rated" : "PG", "imdb" : { "rating" : 7.4, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Die Hard", "plot" : "...", "genres" : ["Action", "Thriller"], "year" : 1988, "rated" : "R", "imdb" : { "rating" : 8.2, "votes" : "...", "id" : "..." } } ...
MoreLikeThis
Use the MoreLikeThis() method to search for documents that are similar to an
input document.
This example uses the following class to specify the input document for the search:
public class MovieSearch { public string Plot { get; set; } = null!; }
The following example searches the movies collection for documents
similar to an object in which the value of the plot field is
"time travel":
var searchDocument = new MovieSearch() { Plot = "time travel", }; var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.MoreLikeThis(searchDocument)) .ToList();
... { "_id" : ObjectId("..."), "title" : "Thrill Seekers", "plot" : "...", "genres" : ["Action", "Sci-Fi", "Thriller"], "year" : 1999, "rated" : "...", "imdb" : { "rating" : "...", "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "About Time", "plot" : "...", "genres" : ["Drama", "Fantasy", "Romance"], "year" : 2013, "rated" : "R", "imdb" : { "rating" : 7.8, "votes" : "...", "id" : "..." } } ...
To learn more about the moreLikeThis operator, see the moreLikeThis
Atlas guide.
Near
Use the Near() method to search for documents in which a specified field is
near a given value. You can perform the search on:
A number field
A date field
A geographic point
The following example searches the movies collection for documents in which
the value of the imdb.rating field is near 8.5. The documents are
returned in order based on how close the value is to 8.5:
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Near(m => m.Imdb.Rating, 8.5, 1)) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Dark Knight", "plot" : "...", "genres" : ["Action", "Crime", "Drama"], "year" : 2008, "rated" : "PG-13", "imdb" : { "rating" : 9.0, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "The Godfather", "plot" : "...", "genres" : ["Crime", "Drama"], "year" : 1972, "rated" : "R", "imdb" : { "rating" : 9.2, "votes" : "...", "id" : "..." } } ...
To learn more about the near operator, see the near
Atlas guide.
Phrase
Use the Phrase() method to search for documents in which a specified field
contains an input string.
The following example searches the movies collection for documents in which
the plot field contains the phrase "time travel":
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Phrase(m => m.Plot, "time travel")) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Time Traveler's Wife", "plot" : "...", "genres" : ["Drama", "Fantasy", "Romance"], "year" : 2009, "rated" : "PG-13", "imdb" : { "rating" : 7.1, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Safety Not Guaranteed", "plot" : "...", "genres" : ["Comedy", "Drama", "Romance"], "year" : 2012, "rated" : "R", "imdb" : { "rating" : 7, "votes" : "...", "id" : "..." } } ...
You can also search the collection for documents that contain either
"time travel" or "space adventure" in the plot field:
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Phrase(m => m.Plot, new List<string>() { "time travel", "space adventure" })) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Time Traveler's Wife", "plot" : "...", "genres" : ["Drama", "Fantasy", "Romance"], "year" : 2009, "rated" : "PG-13", "imdb" : { "rating" : 7.1, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Safety Not Guaranteed", "plot" : "...", "genres" : ["Comedy", "Drama", "Romance"], "year" : 2012, "rated" : "R", "imdb" : { "rating" : 7, "votes" : "...", "id" : "..." } } ...
To learn more about the phrase operator, see the phrase
Atlas guide.
QueryString
Use the QueryString() method to search for documents using a string with
the following operators and delimiters:
ANDORNOT()
The following example searches the movies collection for documents in which
the value of the plot field matches each of the following criteria:
Contains the string
"time"or the string"space"Does not contain the string
"comedy"
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.QueryString(m => m.Plot, "(time OR space) AND NOT comedy")) .ToList();
... { "_id" : ObjectId("..."), "title" : "Interstellar", "plot" : "...", "genres" : ["Adventure", "Drama", "Sci-Fi"], "year" : 2014, "rated" : "PG-13", "imdb" : { "rating" : 8.7, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Tomorrowland", "plot" : "...", "genres" : ["Action", "Adventure", "Family"], "year" : 2015, "rated" : "PG", "imdb" : { "rating" : 6.6, "votes" : "...", "id" : "..." } } ...
To learn more about the queryString operator, see the queryString
Atlas guide.
Range
Use the Range() method to search for documents in which the value of a
specified field falls within a given numeric, date, or string range.
The following example searches the movies collection for all documents with
a year value greater than 2000 and less than 2010:
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search .Range(m => m.Year, SearchRangeBuilder.Gt(2000).Lt(2010))) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Dark Knight", "plot" : "...", "genres" : ["Action", "Crime", "Drama"], "year" : 2008, "rated" : "PG-13", "imdb" : { "rating" : 9.0, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "The Departed", "plot" : "...", "genres" : ["Crime", "Drama", "Thriller"], "year" : 2006, "rated" : "R", "imdb" : { "rating" : 8.5, "votes" : "...", "id" : "..." } } ...
To search for documents in which the value of a specified field is within a
range of strings, you must first create a token index on the field. After you create the
index, you can search for documents based on a range of strings. The following
example returns documents in which the title field value falls between
"A" and "G", compared in lexicographic order:
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search .Range(m => m.Title, SearchRangeV2Builder.Gte("A").Lte("G"))) .ToList();
... { "_id" : ObjectId("..."), "title" : "Apollo 13", "plot" : "...", "genres" : ["Adventure", "Drama", "History"], "year" : 1995, "rated" : "PG", "imdb" : { "rating" : 7.6, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Braveheart", "plot" : "...", "genres" : ["Biography", "Drama", "History"], "year" : 1995, "rated" : "R", "imdb" : { "rating" : 8.3, "votes" : "...", "id" : "..." } } ...
To learn more about the range operator, see the range
Atlas guide.
Regex
Use the Regex() method to search for documents using a regular expression.
The following example searches the movies collection for documents in which
the value of the title field contains exactly six letters:
var regex = "[A-Za-z]{6}"; var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Regex(m => m.Title, regex, allowAnalyzedField: true)) .ToList();
... { "_id" : ObjectId("..."), "title" : "Gandhi", "plot" : "...", "genres" : ["Biography", "Drama", "History"], "year" : 1982, "rated" : "PG", "imdb" : { "rating" : 8.0, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Batman", "plot" : "...", "genres" : ["Action", "Adventure"], "year" : 1989, "rated" : "PG-13", "imdb" : { "rating" : 7.5, "votes" : "...", "id" : "..." } } ...
Note
Running Regex on Analyzed Fields
By default, the regex operator can't run on an analyzed field. You can
allow it to run on an analyzed field by setting the allowAnalyzedField option
to true, as follows:
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Regex(m => m.Title, regex, allowAnalyzedField: true)) .ToList();
Setting the allowAnalyzedField option to true may lead to unexpected
search results. To learn more, see Behavior in the Atlas regex guide.
To learn more about the regex operator, see the regex
Atlas guide.
Span
Use the Span() method to search for text search matches within regions of a
field. You can use this method to find strings which are near each other to
specified degrees of precision.
Note
Span Operator Performance
The span operator is more computationally intensive than other operators
because queries must keep track of positional information.
The following example searches the movies collection for documents in which
the value of the plot field contains the strings "time" and
"travel" within one word of each other:
var searchTerms = new[] { Builders<Movie>.SearchSpan.Term(m => m.Plot, "time"), Builders<Movie>.SearchSpan.Term(m => m.Plot, "travel") }; var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Span(Builders<Movie>.SearchSpan.Near(searchTerms, 1))) .ToList();
... { "_id" : ObjectId("..."), "title" : "The Time Traveler's Wife", "plot" : "...", "genres" : ["Drama", "Fantasy", "Romance"], "year" : 2009, "rated" : "PG-13", "imdb" : { "rating" : 7.1, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "About Time", "plot" : "...", "genres" : ["Drama", "Fantasy", "Romance"], "year" : 2013, "rated" : "R", "imdb" : { "rating" : 7.8, "votes" : "...", "id" : "..." } } ...
To learn more about the span operator, see the span
Atlas guide.
Text
Use the Text() method to search a document for a given string or array of
strings. If there are multiple terms in a given string, MongoDB Search also looks
for a match for each term in the string separately.
The following example searches the movies collection for documents in which
the value of the plot field contains the string "secret agent":
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Text(m => m.Plot, "secret agent")) .ToList();
... { "_id" : ObjectId("..."), "title" : "Spy Kids", "plot" : "...", "genres" : ["Action", "Adventure", "Comedy"], "year" : 2001, "rated" : "PG", "imdb" : { "rating" : 5.4, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "The Spy Who Loved Me", "plot" : "...", "genres" : ["Action", "Adventure", "Thriller"], "year" : 1977, "rated" : "PG", "imdb" : { "rating" : 7.1, "votes" : "...", "id" : "..." } } ...
Tip
Multi-Term Search Behavior
If your search string contains multiple terms, the method also looks for a match for each term in the string separately.
To learn more about the text operator, see the text
Atlas guide.
Wildcard
Use the Wildcard() method to search for documents using special characters in
your search string that can match any character. You can use the following
characters in your search:
Character | Description |
|---|---|
| Matches any single character |
| Matches 0 or more characters |
| Escape character |
The following example searches for documents in which the value of the title
field contains the string "Amer" followed by any other characters:
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Wildcard(m => m.Title, "Amer*", allowAnalyzedField: true)) .ToList();
... { "_id" : ObjectId("..."), "title" : "American Beauty", "plot" : "...", "genres" : ["Drama"], "year" : 1999, "rated" : "R", "imdb" : { "rating" : 8.4, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "American Gangster", "plot" : "...", "genres" : ["Biography", "Crime", "Drama"], "year" : 2007, "rated" : "R", "imdb" : { "rating" : 7.8, "votes" : "...", "id" : "..." } } ...
Note
Running Wildcard on Analyzed Fields
By default, the wildcard operator can't run on an analyzed field. You can
allow it to run on an analyzed field by setting allowAnalyzedField option
to true, as follows:
var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Wildcard(m => m.Title, "Amer*", allowAnalyzedField: true)) .ToList();
Setting the allowAnalyzedField option to true may lead to unexpected
search results. To learn more, see wildcard Behavior.
To learn more about the wildcard operator, see the wildcard
Atlas guide.
Search Multiple Fields
The path parameter is used by the MongoDB Search
operators to specify the field or fields
to be searched. To learn more about what the path parameter may contain, see the Construct a Query Path guide.
Note
Operator Path Support Varies
Not all operators can use all the different types of paths. See the documentation for each individual operator for details on what types of path it supports.
To search multiple indexed fields, use the Multi() method and pass in your fields. Documents which match on any of the specified fields are included in the result set.
The following example searches for the phrase "time travel" in either the plot or the title field:
var result = moviesCollection.Aggregate().Search( Builders<Movie>.Search.Phrase(Builders<Movie>.SearchPath .Multi(m => m.Plot, m => m.Title), "time travel"), indexName: "moviesmulti") .ToList();
... { "_id" : ObjectId("..."), "title" : "The Time Traveler's Wife", "plot" : "...", "genres" : ["Drama", "Fantasy", "Romance"], "year" : 2009, "rated" : "PG-13", "imdb" : { "rating" : 7.1, "votes" : "...", "id" : "..." } } { "_id" : ObjectId("..."), "title" : "Safety Not Guaranteed", "plot" : "...", "genres" : ["Comedy", "Drama", "Romance"], "year" : 2012, "rated" : "R", "imdb" : { "rating" : 7, "votes" : "...", "id" : "..." } } ...
Score Documents
MongoDB Server assigns a relevance score to every document that it returns from a MongoDB Search query. The query returns the documents in order from highest score to lowest. To learn more about how scores are assigned, see the score Atlas guide.
The score assigned to a returned document is part of the document's metadata. You can include each returned document's score along with the result set by using a $project stage in your aggregation pipeline.
The following example searches the movies collection for documents in which the value of the title field contains exactly six letters and uses a $project stage to add a field named score to the returned documents:
var regex = "[A-Za-z]{6}"; var result = moviesCollection.Aggregate() .Search(Builders<Movie>.Search.Regex(m => m.Title, regex, allowAnalyzedField: true), indexName: "moviescore") .Project<Movie>(Builders<Movie>.Projection .Include(m => m.Id) .Include(m => m.Title) .Include(m => m.Plot) .MetaSearchScore(m => m.Score)) .ToList();
... { "_id" : ObjectId("..."), "title" : "Gandhi", "plot" : "...", "score" : 1.0 } { "_id" : ObjectId("..."), "title" : "Batman", "plot" : "...", "score" : 1.0 } ...
Modify MongoDB Search Behavior
You can modify the behavior of the Search() method by passing
a SearchOptions object as a parameter.
The SearchOptions class contains the following properties:
Property | Description |
|---|---|
| The options for counting the search results. Data type: SearchCountOptions Default: null |
| The options for displaying search terms in their original context. Data type: SearchHighlightOptions<TDocument> Default: null |
| The index to use for the search. Data type: stringDefault: null |
| A flag that specifies whether to perform a full document lookup on
the database or to return only stored source fields directly from
MongoDB Search. Data type: booleanDefault: false |
| A flag that specifies whether to return detailed information about the
score for each document in the results. Data type: booleanDefault: false |
| The starting point for pagination. When set, the search retrieves documents
starting immediately after the specified reference point. Data type: stringDefault: null |
| The end point for pagination. When set, the search retrieves documents
starting immediately before the specified reference point. Data type: stringDefault: null |
| The sorting criteria to apply to the results. Data type: SortDefinition<TDocument> Default: null |
| The options for tracking search terms. Data type: SearchTrackingOptions Default: null |
SearchAfter Example
The following example paginates the results of a MongoDB Search operation by performing the following actions:
Defines a projection that uses the
MetaSearchSequenceToken()builder method, which specifies aPaginationTokento contain the point of referenceCreates a
SearchOptionsinstance and sets the index and sort criteria to useRuns an initial search to find documents that have a
plotfield value containing the text"time travel", applying the projection and options to the operationSets the
SearchAfterproperty of the sameSearchOptionsinstance to instruct the next search to begin after the base search's first resultRuns another search operation that has the same matching criteria and applies the search options to paginate the results
var projection = Builders<Movie>.Projection .Include(x => x.Title) .MetaSearchSequenceToken(x => x.PaginationToken); var searchDefinition = Builders<Movie>.Search.Text(m => m.Plot, "time travel"); var searchOptions = new SearchOptions<Movie> { IndexName = "default", Sort = Builders<Movie>.Sort.Ascending(m => m.Id) }; // Runs the base search operation var baseSearchResults = moviesCollection.Aggregate() .Search(searchDefinition, searchOptions) .Project<Movie>(projection) .ToList(); if (baseSearchResults.Count == 0) return baseSearchResults; // Sets the starting point for the next search searchOptions.SearchAfter = baseSearchResults[0].PaginationToken; var result = moviesCollection.Aggregate() .Search(searchDefinition, searchOptions) .Project<Movie>(projection) .ToList();
... { "_id" : ObjectId("..."), "title" : "About Time", "plot" : "...", "genres" : ["Comedy", "Drama", "Romance"], "year" : 2013, "rated" : "R", "imdb" : { "rating" : 7.8, "votes" : "...", "id" : "..." } } ...
Tip
Pagination Documentation
To learn more about MongoDB Search pagination, see Paginate the Results in the Atlas documentation.