Overview
In this guide, you can learn how to use Django MongoDB Backend to run MongoDB Search queries on a collection. MongoDB Search enables you to perform full-text searches on your MongoDB collections. MongoDB Search indexes specify the behavior of the search and which fields to index.
Sample Data
The examples in this guide use the Movie and Theater models, which represent
the sample_mflix.movies and sample_mflix.theaters collections from the
Atlas sample datasets. The model classes have the
following definitions:
from django.db import models from django.contrib.gis.db import models from django_mongodb_backend.fields import ArrayField class Movie(models.Model): title = models.CharField(max_length=200) plot = models.TextField(blank=True) runtime = models.IntegerField(default=0) genres = ArrayField(models.CharField(max_length=100), null=True, blank=True) class Meta: db_table = "movies" managed = False def __str__(self): return self.title class Theater(models.Model): theater_id = models.IntegerField(default=0, db_column="theaterId") geo = models.PointField(db_column="location.geo") class Meta: db_table = "theaters" managed = False def __str__(self): return self.theater_id
Tip
GeoDjango Fields
The Theater model uses a GeoDjango PointField named geo to
store geospatial data. To learn more about GeoDjango fields, see
the Model Geospatial Data guide.
The Movie and Theater models include an inner Meta class, which specifies
model metadata, and a __str__() method, which defines the
model's string representation. To learn about these
model features, see Define a Model in the
Create Models guide.
Run Code Examples
You can use the Python interactive shell to run the code examples. To enter the shell, run the following command from your project's root directory:
python manage.py shell
After entering the Python shell, ensure that you import the following models and modules:
from <your application name>.models import Movie, Theater from django_mongodb_backend.expressions import ( SearchEquals, SearchAutocomplete, SearchExists, SearchIn, SearchPhrase, SearchQueryString, SearchRange, SearchRegex, SearchText, SearchWildcard, SearchGeoShape, SearchGeoWithin, SearchMoreLikeThis, CompoundExpression, SearchScoreOption )
To learn how to create a Django application that uses the Movie
model and the Python interactive shell to interact with MongoDB documents,
visit the Get Started tutorial.
Run a MongoDB Search Query
Important
Index Requirements
Before running a MongoDB Search query, you must create a Search index on the relevant fields. To learn how to create Search indexes, see Search Indexes in the Create Indexes guide.
To run a MongoDB Search query, use the annotate() method from
Django's QuerySet API. Pass your MongoDB Search criteria, including
your search operator, as a score argument to annotate(). The following
code shows the basic syntax for running a Search query:
Model.objects.annotate( score=<Search Operator>(path="<field name", <additional arguments>) )
To specify Search operators, use the expression classes provided
by the django_mongodb_backend.expressions module. Each class
corresponds to a Search operator.
The following sections show how to run Search queries by using each supported expression class.
SearchEquals
Important
Additional Index Requirements
Before using the SearchEquals expression in a Search query,
create a Search index that indexes the relevant field
as the token type.
Starting in Django MongoDB Backend v5.2.2, you can use the field_mappings argument to create this index.
The SearchEquals expression matches documents in which a field
is equal to a specified value. This corresponds to the MongoDB equals
operator.
To use this operator, pass the following arguments to the SearchEquals() constructor:
path: The name of the field to search. You can specify a string value or aFinstance.value: The value to match. You can specify a string value or aValueinstance.score: (Optional) A SearchScoreOption instance that configures the relevance score.
The following example uses the SearchEquals operator to query the
sample_mflix.movies collection for documents that have a title
value of "Finding Nemo":
Movie.objects.annotate(score=SearchEquals(path="title", value="Finding Nemo"))
SearchAutocomplete
Important
Additional Index Requirements
Before using the SearchAutocomplete expression in a Search query,
create a Search index that indexes the relevant field
as the autocomplete type.
Starting in Django MongoDB Backend v5.2.2, you can use the field_mappings argument to create this index.
The SearchAutocomplete expression searches for a word or phrase that contains a
sequence of characters from an incomplete input string. This corresponds to the
MongoDB autocomplete operator.
To use this operator, pass the following arguments to the SearchAutocomplete() constructor:
path: The name of the field to search. You can specify a string value or aFinstance.query: The input string to autocomplete. You can specify a string value or aValueinstance.fuzzy: (Optional) A dictionary that enables fuzzy matching and allows you to configure its behavior. For example, you can specify{"maxEdits": 1}to allow one character change before matching the search term. To view all available values, see the autocomplete options in the MongoDB Atlas documentation.token_order: (Optional) A string that configures token sequence behavior. You can set this value to"sequential"or"any".score: (Optional) A SearchScoreOption instance that configures the relevance score.
The following example uses the SearchAutocomplete expression to query the
sample_mflix.movies collection for documents that have a title
value beginning with "First":
Movie.objects.annotate(score=SearchAutocomplete(path="title", query="First"))
SearchExists
The SearchExists expression matches documents in which a specified field
exists. This corresponds to the MongoDB exists operator.
To use this operator, pass the following arguments to the SearchExists() constructor:
path: The name of the field to match. You can specify a string value or aFinstance.score: (Optional) A SearchScoreOption instance that configures the relevance score.
The following example uses the SearchExists expression to query the
sample_mflix.movies collection for documents that have a plot
field:
Movie.objects.annotate(score=SearchExists(path="plot"))
SearchIn
Important
Additional Index Requirements
Before using the SearchIn expression in a Search query,
create a Search index on the relevant field. If you are querying a string field,
you must index it as the token type.
Starting in Django MongoDB Backend v5.2.2, you can use the field_mappings argument to create this index.
The SearchIn expression matches documents in which a field's value
is in a given list. This corresponds to the MongoDB in operator.
To use this operator, pass the following arguments to the SearchIn() constructor:
path: The name of the field to search. You can specify a string value or aFinstance.value: The list of values to match. You can specify a list of values or aValueinstance.score: (Optional) A SearchScoreOption instance that configures the relevance score.
The following example uses the SearchIn expression to query the
sample_mflix.movies collection for documents that have a runtime
value of 100, 200, or 300 minutes:
Movie.objects.annotate(score=SearchIn(path="runtime", value=[100, 200, 300]))
SearchPhrase
The SearchPhrase expression matches exact or near-exact sequences of terms in a field.
This corresponds to the MongoDB phrase operator.
To use this operator, pass the following arguments to the SearchPhrase() constructor:
path: The name of the field to search. You can specify a string value or aFinstance.query: The phrase to match. You can specify a string or a list of strings.slop: (Optional) The maximum number of terms allowed between phrase terms.synonyms: (Optional) The name of a synonym mapping defined in your Search index.score: (Optional) A SearchScoreOption instance that configures the relevance score.
The following example uses the SearchPhrase expression to query the
sample_mflix.movies collection for documents that have the phrase "space adventure"
in their plot field, allowing up to 2 words between these terms:
Movie.objects.annotate(score=SearchPhrase(path="plot", query="space adventure", slop=2))
SearchQueryString
The SearchQueryString operator allows you to perform text, wildcard, regular expression,
fuzzy, and range searches on string fields. This corresponds to the MongoDB
queryString operator.
To use this operator, pass the following arguments to the SearchQueryString() constructor:
path: The name of the field to search. You can specify a string value or aFinstance.query: The Lucene-style query string. To learn more about Lucene query syntax, see the Apache Lucene documentation.score: (Optional) A SearchScoreOption instance that configures the relevance score.
The following example uses the SearchQueryString expression to query the
sample_mflix.movies collection for documents that match a Lucene-style
query on the plot field:
Movie.objects.annotate(score=SearchQueryString(path="plot", query="romance AND (paris OR tokyo)"))
SearchRange
Important
Additional Index Requirements
Before using the SearchRange expression in a Search query,
create a Search index on the relevant field. If you are querying a string field,
you must index it as the token type.
Starting in Django MongoDB Backend v5.2.2, you can use the field_mappings argument to create this index.
The SearchRange expression searches for values within a specified range.
You can provide a range of numeric, date, string, or ObjectId values.
This corresponds to the MongoDB range operator.
To use this operator, pass the following arguments to the SearchRange() constructor:
path: The name of the field to search. You can specify a string value or aFinstance.lt: (Optional) Exclusive upper bound (<)lte: (Optional) Inclusive upper bound (<=)gt: (Optional) Exclusive lower bound (>)gte: (Optional) Inclusive lower bound (>=)score: (Optional) A SearchScoreOption instance that configures the relevance score.
The following example uses the SearchRange expression to query the
sample_mflix.movies collection for documents that have a runtime
value between 90 and 120 minutes.
Movie.objects.annotate(score=SearchRange(path="runtime", gt=90, lt=120))
SearchRegex
The SearchRegex expression matches string field values by using a regular expression.
This corresponds to the MongoDB regex operator.
To use this operator, pass the following arguments to the SearchRegex() constructor:
path: The name of the field to search. You can specify a string value or aFinstance.query: The regular expression string used to search the field contents.allow_analyzed_field: (Optional) A boolean value that indicates whether to allow matching against analyzed fields. The default value isFalse.score: (Optional) A SearchScoreOption instance that configures the relevance score.
The following example uses the SearchRegex expression to query the
sample_mflix.movies collection for documents that have a title
value that includes the word "winter":
Movie.objects.annotate(score=SearchRegex(path="title", query=r".*winter.*"))
SearchText
The SearchText expression performs a full-text search on string fields.
This corresponds to the MongoDB text operator.
To use this operator, pass the following arguments to the SearchText() constructor:
path: The name of the field to search. You can specify a string value or aFinstance.query: The search term or phrase.fuzzy: (Optional) A dictionary that enables fuzzy matching and allows you to configure its behavior. For example, you can specify{"maxEdits": 1}to allow one character change before matching the search term.match_criteria: (Optional) Whether to match documents that contain"all"or"any"of the search terms. The default value is"any".synonyms: (Optional) The name of a synonym mapping defined in your Atlas index.score: (Optional) A SearchScoreOption instance that configures the relevance score.
The following example uses the SearchText expression to query the
sample_mflix.movies collection for documents that have "sudden disappearance" in their
plot field, with fuzzy matching enabled:
Movie.objects.annotate(score=SearchText( path="plot", query="sudden disappearance", fuzzy={"maxEdits": 2}, match_criteria="all" ))
SearchWildcard
The SearchWildcard expression matches strings by using wildcard patterns.
This corresponds to the MongoDB wildcard operator.
To use this operator, pass the following arguments to the SearchWildcard() constructor:
path: The name of the field to search. You can specify a string value or aFinstance.query: A wildcard string that may include the*character, to match any sequence of characters, and the?character, to match any single character.allow_analyzed_field: (Optional) A boolean value that allows matching against analyzed fields. The default value isFalse.score: (Optional) A SearchScoreOption instance that configures the relevance score.
The following example uses the SearchWildcard expression to query the
sample_mflix.movies collection for documents that have a title
starting with "Star" and ending with any characters:
Movie.objects.annotate(score=SearchWildcard(path="title", query="Star*"))
SearchGeoShape
Important
Additional Index Requirements
Before using the SearchGeoShape expression in a Search query,
create a Search index that indexes the relevant field as
the geo type
with the indexShapes property set to true. Starting in Django MongoDB Backend
v5.2.2, you can use the field_mappings
argument to create this index.
The SearchGeoShape expression filters documents based on spatial relationships with a shape.
This corresponds to the MongoDB geoShape operator.
To use this operator, pass the following arguments to the SearchGeoShape() constructor:
path: The name of the field to search. You can specify a string value or aFinstance.relation: The spatial relation to test. Valid values include"within","intersects", and"disjoint".geometry: A GeoJSON geometry object to compare against.score: (Optional) A SearchScoreOption instance that configures the relevance score.
The following example uses the SearchGeoShape expression to query the
sample_mflix.theaters collection for documents that have a geo value
within a specified polygon:
chicago = { "type": "Polygon", "coordinates": [ [ [-87.851, 41.976], [-87.851, 41.653], [-87.651, 41.653], [-87.651, 41.976], [-87.851, 41.976], ] ] } theaters = Theater.objects.annotate(score=SearchGeoShape( path="geo", relation="within", geometry=chicago ))
SearchGeoWithin
Important
Additional Index Requirements
Before using the SearchGeoWithin expression in a Search query,
create a Search index that indexes the query field as
the geo type.
Starting in Django MongoDB Backend v5.2.2, you can use the field_mappings
argument to create this index.
The SearchGeoWithin expression filters documents with geo fields contained within a specified shape.
This corresponds to the MongoDB geoWithin operator.
To use this operator, pass the following arguments to the SearchGeoWithin() constructor:
path: The name of the field to search. You can specify a string value or aFinstance.kind: The GeoJSON geometry type:"circle","box", or"geometry".geometry: The GeoJSON geometry defining the spatial boundary.score: (Optional) A SearchScoreOption instance that configures the relevance score.
The following example uses the SearchGeoWithin operator to query the
sample_mflix.theaters collection for documents that have a geo
value within a specified circle:
circle = { "center": {"type": "Point", "coordinates": [-73.98, 40.75]}, "radius": 5000 } theaters = Theater.objects.annotate(score=SearchGeoWithin( path="geo", kind="circle", geometry=circle ))
SearchMoreLikeThis
The SearchMoreLikeThis expression finds documents similar to the provided examples.
This corresponds to the MongoDB moreLikeThis operator.
To use this operator, pass the following arguments to the SearchMoreLikeThis() constructor:
documents: A list of example documents or expressions that serve as references for similarity.score: (Optional) A SearchScoreOption instance that configures the relevance score.
The following example uses the SearchMoreLikeThis expression to query the
sample_mflix.movies collection for documents that are similar to a
provided example document:
Movie.objects.annotate(score=SearchMoreLikeThis([ {"title": "The Godfather"}, {"genres": ["Crime", "Drama"]} ]))
Combine Expressions
You can perform MongoDB Search queries that combine multiple search expressions in the following ways:
Use the CompoundExpression Class
The CompoundExpression expression allows you to use boolean logic to combine
multiple Search expressions. This corresponds to the MongoDB compound
operator.
You must pass one or more of the following
arguments to the CompoundExpression() constructor:
must: A list of expressions that documents must matchshould: A list of expressions that documents should matchmust_not: A list of expressions that documents must not matchfilter: A list of expressions that filter the results
You can also pass the following optional arguments:
minimum_should_match: The minimum number ofshouldclauses that documents must matchscore: A SearchScoreOption instance that configures the relevance score
This example uses the CompoundExpression expression to query the
sample_mflix.movies collection for documents that match the following criteria:
plotfield existsplotfield contains the text"fast-paced"genresfield does not contain either"Romance"or"Comedy"
plot_exists = SearchExists(path="plot") plot_text = SearchText(path="plot", query="fast-paced") genres_range = SearchIn(path="genres", value=["Romance", "Comedy"]) Movie.objects.annotate( score=CompoundExpression( must=[plot_exists, plot_text], must_not=[genres_range] ) )
Use Bitwise Operators
You can use the following bitwise operators to combine Search expressions:
&: Represents a logical AND operation|: Represents a logical OR operation~: Represents a logical NOT operation
This example uses the | operator to query the
sample_mflix.movies collection for documents that match either
or both of the following criteria:
plotfield contains the text"heartwarming"genresfield contains either"Romance"or"Comedy"
expr = SearchText(path="plot", query="heartwarming") | SearchIn(path="genres", value=["Romance", "Comedy"]) Movie.objects.annotate(score=expr)
Configure Relevance Scores
MongoDB assigns a relevance score to every document returned in a Search query. The documents included in a result set are ordered from highest to lowest relevance score.
You can use the SearchScoreOption expression to customize how MongoDB calculates
and applies relevance scores. The SearchScoreOption() constructor accepts
the following arguments:
boost: Increases the score of documents that match a specified expressionconstant: Applies a fixed score to all matchesfunction: Applies a function to compute the scorepath: Scores documents based on the value of a field
Tip
To learn more about relevance scores, see Score the Documents in the Results in the MongoDB Atlas documentation.
The following example boosts the relevance score of documents that match the
SearchEquals expression by a factor of 3:
boost = SearchScoreOption({"boost": {"value": 3}}) Movie.objects.annotate( score=SearchEquals( path="title", value="Life of Pi", score=boost ) )
Additional Information
To learn more about creating MongoDB Search indexes, see Search Indexes in the Create Indexes guide.
To learn more about MongoDB Search queries, see MongoDB Search Overview in the MongoDB Atlas documentation.