Perform Raw Database Queries
On this page
Overview
In this guide, you can learn how to use Django MongoDB Backend to run raw queries on your MongoDB database. Raw queries allow you to query the database by using MongoDB's aggregation pipeline syntax rather than Django methods.
The Django QuerySet API provides a QuerySet.raw()
method, which allows
you to perform raw SQL queries on relational databases. However, Django MongoDB Backend
does not support the raw()
method. Instead, the ODM provides the
QuerySet.raw_aggregate()
method, which you can use to send instructions
to the database in pipeline stages.
Sample Data
The examples in this guide use the Movie
and Theater
models, which
represent collections in the sample_mflix
database from the Atlas sample datasets.
The model classes have the following definitions:
from django.db import models from django_mongodb_backend.fields import EmbeddedModelField, ArrayField from django_mongodb_backend.managers import MongoManager class Movie(models.Model): title = models.CharField(max_length=200) plot = models.TextField(null=True) runtime = models.IntegerField(default=0) released = models.DateTimeField("release date", null=True) awards = EmbeddedModelField(Award) genres = ArrayField(models.CharField(max_length=100), blank=True) objects = MongoManager() class Meta: db_table = "movies" def __str__(self): return self.title class Theater(models.Model): theaterId = models.IntegerField(default=0) objects = MongoManager() class Meta: db_table = "theaters" def __str__(self): return self.title
To learn how to create a Django application that uses a similar Movie
model to interact with MongoDB documents, visit the django-get-started
tutorial.
Run Raw Queries
To run a raw database query, pass an aggregation pipeline
to the QuerySet.raw_aggregate()
method. Aggregation pipelines
contain one or more stages that provide instructions on how to
process documents. After calling the raw_aggregate()
method,
Django MongoDB Backend passes your pipeline to the pymongo.collection.Collection.aggregate()
method and returns the query results as model objects.
Tip
To learn more about constructing aggregation pipelines, see Aggregation Pipeline in the MongoDB Server manual.
This section shows how to use the raw_aggregate()
method
to perform the following tasks:
Filter and Project Document Fields
This example runs a raw database query by calling the
raw_aggregate()
method on your Movie
objects,
which represent documents in the sample_mflix.movies
collection. The code passes the following aggregation pipeline stages
to raw_aggregate()
:
$match
: Filters for documents that have atitle
field value of"The Parent Trap"
$project
: Includes thetitle
andreleased
fields of the returned model objects
from sample_mflix.models import Movie movies = Movie.objects.raw_aggregate([ {"$match": {"title": "The Parent Trap"}}, {"$project": { "title": 1, "released": 1 } }]) for m in movies: print(f"Plot of {m.title}, released on {m.released}: {m.plot}\n")
Plot of The Parent Trap, released on 1961-06-21 00:00:00+00:00: Teenage twin girls swap places and scheme to reunite their divorced parents. Plot of The Parent Trap, released on 1998-07-29 00:00:00+00:00: Identical twins, separated at birth and each raised by one of their biological parents, discover each other for the first time at summer camp and make a plan to bring their wayward parents back together.
Note
The raw_aggregate()
method returns deferred model instances,
which means that you can load fields omitted by the $project
stage
on demand. In the preceding example, the query retrieves the title
and released
fields. The print statement runs a separate query
to retrieve the plot
field.
Run an Atlas Search Query
You can run Atlas Search queries on your database to perform fine-grained text searches. These queries provide advanced search functionality, such as matching text phrases, scoring results for relevance, and highlighting matches.
To specify an Atlas Search query, create an Atlas Search index
that covers the fields you want to query. Then, pass a $search
or $searchMeta
stage in an aggregation pipeline parameter to
the raw_aggregate()
method.
Important
You cannot use Django MongoDB Backend to create Atlas Search indexes.
For instructions on using the PyMongo driver to create an Atlas Search index, see Atlas Search and Vector Search Indexes in the PyMongo documentation.
For instructions on alternative methods of creating search indexes, see Create an Atlas Search Index in the Atlas documentation.
This example runs an Atlas Search query by passing the $search
pipeline
stage to the raw_aggregate()
method. The code performs the following
actions:
Specifies the Atlas Search index that covers the
plot
fieldQueries for documents whose
plot
values contain the string"whirlwind romance"
with no more than3
words between themReturns portions of the
plot
string values that match the query and metadata that indicates where the matches occurredIncludes the
title
field and thehighlight
, or matching text, of each result
movies = Movie.objects.raw_aggregate([ { "$search": { "index": "<search-index-name>", "phrase": { "path": "plot", "query": "whirlwind romance", "slop": 3 }, "highlight": { "path": "plot" } } }, { "$project": { "title": 1, "highlight": {"$meta": "searchHighlights"} } } ]) for m in movies: print(f"Title: {m.title}, text match details: {m.highlight}\n")
Title: Tokyo Fiancèe, text match details: [{'score': 2.3079638481140137, 'path': 'plot', 'texts': [{'value': 'A young Japanophile Belgian woman in Tokyo falls into a ', 'type': 'text'}, {'value': 'whirlwind', 'type': 'hit'}, {'value': ' ', 'type': 'text'}, {'value': 'romance', 'type': 'hit'}, {'value': ' with a Francophile Japanese student.', 'type': 'text'}]}] Title: Designing Woman, text match details: [{'score': 2.3041324615478516, 'path': 'plot', 'texts': [{'value': 'A sportswriter and a fashion-designer marry after a ', 'type': 'text'}, {'value': 'whirlwind', 'type': 'hit'}, {'value': ' ', 'type': 'text'}, {'value': 'romance', 'type': 'hit'}, {'value': ', and discover they have little in common.', 'type': 'text'}]}] Title: Vivacious Lady, text match details: [{'score': 2.220963478088379, 'path': 'plot', 'texts': [{'value': 'On a quick trip to the city, young university professor Peter Morgan falls in love with nightclub performer Francey Brent and marries her after a ', 'type': 'text'}, {'value': 'whirlwind', 'type': 'hit'}, {'value': ' ', 'type': 'text'}, {'value': 'romance', 'type': 'hit'}, {'value': '. ', 'type': 'text'}]}] Title: Ek Hasina Thi, text match details: [{'score': 3.11773419380188, 'path': 'plot', 'texts': [{'value': 'The ', 'type': 'text'}, {'value': 'whirlwind', 'type': 'hit'}, {'value': ' ', 'type': 'text'}, {'value': 'romance', 'type': 'hit'}, {'value': ' turns sour when she is framed for his underworld crimes. ', 'type': 'text'}]}] Title: Kick, text match details: [{'score': 2.00649356842041, 'path': 'plot', 'texts': [{'value': 'An adrenaline junkie walks away from a ', 'type': 'text'}, {'value': 'whirlwind', 'type': 'hit'}, {'value': ' ', 'type': 'text'}, {'value': 'romance', 'type': 'hit'}, {'value': ' and embraces a new life as a thief, though he soon finds himself pursued by veteran police officer and engaged in a turf war with a local gangster.', 'type': 'text'}]}] Title: A Tale of Winter, text match details: [{'score': 3.3978850841522217, 'path': 'plot', 'texts': [{'value': 'Felicie and Charles have a serious if ', 'type': 'text'}, {'value': 'whirlwind', 'type': 'hit'}, {'value': ' holiday ', 'type': 'text'}, {'value': 'romance', 'type': 'hit'}, {'value': '. ', 'type': 'text'}]}]
Important
When running the preceding example, ensure that you replace
the <search-index-name>
placeholder with the name of your
Atlas Search index that covers the plot
field.
Query Geospatial Data
You can use the raw_aggregate()
method to run queries
on fields containing geospatial data. Geospatial data represents
a geographic location on the surface of the Earth or on a
Euclidean plane.
To run a geospatial query, create a 2d
or 2dsphere
index on fields
containing geospatial data. Then, pass one of the following
query operators in an aggregation pipeline parameter to
the raw_aggregate()
method:
$near
$geoWithin
$nearSphere
$geoIntersects
Important
You cannot use Django MongoDB Backend to create 2d
or 2dsphere
indexes.
For instructions on using the PyMongo driver to create geospatial indexes, see Geospatial Indexes in the PyMongo documentation.
For instructions on using the MongoDB Shell to create geospatial indexes, see Geospatial Indexes in the MongoDB Server manual.
This example runs a geospatial query by passing the $match
and
$geoWithin
pipeline stages to the raw_aggregate()
method. The
code performs the following actions:
Specifies a list of coordinates that represent Chicago's boundaries
Queries for documents in which the
location.geo
field stores a location within the Chicago areaRetrieves and prints the
theaterId
values of each movie theater in Chicago
chicago_bounds = { "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.raw_aggregate([ { "$match": { "location.geo": { "$geoWithin": { "$geometry": chicago_bounds } } } }, { "$project": { "theaterId": 1 } } ]) for t in theaters: print(f"Theater ID: {t.theaterId}")
Theater ID: 2447 Theater ID: 311 Theater ID: 320 Theater ID: 2960 Theater ID: 2741 Theater ID: 306 Theater ID: 322 Theater ID: 319 Theater ID: 2862 Theater ID: 1777 Theater ID: 814 Theater ID: 323
Additional Information
To view more examples that use the raw_aggregate()
method,
see QuerySet API Reference
in the Django MongoDB Backend API documentation.
To learn more about running aggregation operations, see Aggregation Operations in the MongoDB Server manual.
To learn more about Atlas Search, see Atlas Search in the Atlas documentation.
To learn more about running geospatial queries, see Geospatial Queries in the MongoDB Server manual.