Overview
In this guide, you can learn how to use Django MongoDB Backend to run Atlas Search queries on a collection. Atlas Search enables you to perform full-text searches on collections hosted on MongoDB Atlas. Atlas 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_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): theaterId = models.IntegerField(default=0) location = models.JSONField(null=True) class Meta: db_table = "theaters" managed = False def __str__(self): return self.theaterId
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 an Atlas Search Query
Important
Index Requirements
Before running an Atlas Search query, you must create an Atlas Search index on the relevant fields. To learn how to create Atlas Search indexes, see Atlas Search Indexes in the Create Indexes guide.
To run an Atlas Search query, use the annotate()
method from
Django's QuerySet
API. Pass your Atlas Search criteria, including
your search operator, as a score
argument to annotate()
. The following
code shows the basic syntax for running an Atlas Search query:
Model.objects.annotate( score=<Search Operator>(path="<field name", <additional arguments>) )
To specify Atlas Search operators, use the expression classes provided
by the django_mongodb_backend.expressions
module. Each class
corresponds to an Atlas Search operator.
The following sections show how to run Atlas Search queries by using each supported expression class.
SearchEquals
Important
Additional Index Requirements
Before using the SearchEquals
expression in an Atlas Search query,
create an Atlas Search index that indexes the relevant field
as the token type.
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 aF
instance.value
: The value to match. You can specify a string value or aValue
instance.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 an Atlas Search query,
create an Atlas Search index that indexes the relevant field
as the autocomplete type.
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 aF
instance.query
: The input string to autocomplete. You can specify a string value or aValue
instance.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 aF
instance.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 an Atlas Search query,
create an Atlas Search index on the relevant field. If you are querying a string
field,
you must index it as the token type.
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 aF
instance.value
: The list of values to match. You can specify a list of values or aValue
instance.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
Important
Additional Index Requirements
Before using the SearchPhrase
expression in an Atlas Search query,
create an Atlas Search index on the relevant field. You must index the query field as the
string type with the indexOptions
property set to positions
or offsets
.
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 aF
instance.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 Atlas 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 aF
instance.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 an Atlas Search query,
create an Atlas Search index on the relevant field. If you are querying a string
field,
you must index it as the token type.
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 aF
instance.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 aF
instance.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 aF
instance.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 aF
instance.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 an Atlas Search query,
create an Atlas Search index that indexes the relevant field as
the geo type with the indexShapes
property set to true
.
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 aF
instance.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 location
within a specified polygon:
polygon = {"type": "Polygon", "coordinates": [[[0, 0], [3, 6], [6, 1], [0, 0]]]} Theater.objects.annotate(score=SearchGeoShape( path="location", relation="within", geometry=polygon ))
SearchGeoWithin
Important
Additional Index Requirements
Before using the SearchGeoWithin
expression in an Atlas Search query,
create an Atlas Search index that indexes the query field as
the geo type.
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 aF
instance.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 location
value within a specified circle:
circle = { "center": {"type": "Point", "coordinates": [-73.98, 40.75]}, "radius": 5000 } Theater.objects.annotate(score=SearchGeoWithin( path="location", 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 Atlas 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 Atlas 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 ofshould
clauses 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:
plot
field existsplot
field contains the text"fast-paced"
genres
field 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 Atlas 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:
plot
field contains the text"heartwarming"
genres
field 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 an Atlas 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 Atlas Search indexes, see Atlas Search Indexes in the Create Indexes guide.
To learn more about Atlas Search queries, see Atlas Search Overview in the MongoDB Atlas documentation.