Create Indexes
On this page
Overview
In this guide, you can learn how to create MongoDB indexes by using your Django models. Indexes can improve the efficiency of queries and provide additional query and document storage functionality.
Without indexes, MongoDB must scan every document in a collection to find the documents that match a query. These collection scans are slow and can negatively affect the performance of your application. However, if an appropriate index exists for a query, MongoDB can use the index to limit the documents it inspects.
Django provides the Index
class, which you can use to create an
index on your model. Django MongoDB Backend creates the same index on your
MongoDB collection that the model represents.
Tip
To learn more about the Index
class, see Index
in the Django documentation.
Sample Data
The examples in this guide use the Recipe
model, which contains an
embedded Nutrition
model as the value of its nutrition
field.
These model classes have the following definitions:
from django.db import models from django.db.models import Q, F from django_mongodb_backend.models import EmbeddedModel from django_mongodb_backend.fields import EmbeddedModelField, ArrayField class Nutrition(EmbeddedModel): calories = models.IntegerField(default=0) carb_grams = models.IntegerField(default=0) protein_grams = models.IntegerField(default=0) class Recipe(models.Model): title = models.CharField(max_length=200) cuisine = models.CharField(max_length=200) cook_time = models.IntegerField(default=0) allergens = ArrayField(models.CharField(max_length=100), null=True, blank=True) nutrition = EmbeddedModelField(Nutrition, null=True, blank=True) class Meta: db_table = "recipes" def __str__(self): return self.title
In the Recipe
model's Meta
class, the db_table = "recipes"
option
instructs Django MongoDB Backend to map the Recipe
model to a MongoDB collection
called recipes
. To learn how to create a Django application that
uses models to interact with MongoDB collections, visit the
Get Started with Django MongoDB Backend tutorial.
Create an Index
To create an index on your model, specify the indexes
option
in your model's Meta
class. Set the value of this indexes
option
to a list of the indexes you want to create, as shown in the following
code:
class Meta: indexes = [ models.Index(<first index definition>), models.Index(<second index definition>), # add more indexes here ]
To define your index, pass the following arguments to the models.Index()
method:
fields
: Specifies a list of fields to index. This argument is required.name
: Specifies the index name. This argument is optional, and Django automatically creates an index name if you don't provide one.condition
: Specifies a subset of documents to index. This argument is optional. To learn more about thecondition
argument, see the Partial Indexes section of this guide.
After you apply your database migrations, Django MongoDB Backend creates the same indexes on the MongoDB collection.
Tip
To learn how to create and apply database migrations, see Migrations in the Django documentation.
This section shows how to create the following index types:
Single Field Index
Single field indexes store information from a single field in a collection.
By default, all MongoDB collections have an index on the _id
field.
The following example updates the Recipe
model's Meta
class to create
a single field index on the title
field, which Django MongoDB Backend creates
on the recipes
collection:
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["title"], name="title_idx"), ]
Alternatively, you can set the db_index
option on your model's title
field
to create the index, as shown in the following code:
class Recipe(models.Model): title = models.CharField(max_length=200, db_index=True)
Compound Index
Compound indexes collect and sort data from multiple fields in a collection. MongoDB groups data by the first field specified in the index, and then by each subsequent field.
The following example updates the Recipe
model's Meta
class to create
a compound index on the title
and cook_time
fields, which Django MongoDB Backend creates
on the recipes
collection:
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["title", "cook_time"]), ]
Multikey Index
Multikey indexes collect and sort data from array fields. When you create an index on an array field, MongoDB automatically sets that index as a multikey index.
The following example updates the Recipe
model's Meta
class to create
a compound index on the allergens
array field, which Django MongoDB Backend creates
on the recipes
collection:
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["allergens"], name="allergy_idx"), ]
Embedded Document Index
You can create indexes on fields that store embedded model values, which MongoDB represents as embedded documents.
The following example updates the Recipe
model's Meta
class to create
an index on the nutrition
embedded model field, which Django MongoDB Backend creates
on the recipes
collection:
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["nutrition"]), ]
Important
The index created in the preceding example is only used in queries that
specify the entire embedded document. Queries on a specific field within
the embedded document do not use the index. However, you can index
fields within the embedded document by adding an inner Meta
class
to the Nutrition
model and specifying the indexes
option.
Advanced Index Configuration
This section shows how to create the following advanced index types:
Partial Indexes
Partial indexes index only the documents in a collection that meet specified filter criteria, which reduces storage use and performance costs.
To create a partial index, pass the condition
argument to the models.Index()
method. Set the condition value to a Q
object that includes the filter
criteria. When using the condition
argument, you must also pass the name
argument to models.Index()
.
Tip
To learn more about Q
objects, see Q
in the Django documentation.
The following example updates the Recipe
model's Meta
class to create
a partial index on the cuisine
field, instructing Django MongoDB Backend to
only index documents that have a cook_time
value less than 30
:
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["cuisine"], condition=Q(cook_time__lt=30), name="fast_cuisine_idx"), ]
Unique Indexes
Unique indexes allow you to prevent indexed fields from storing duplicate values. On a single field, unique indexes ensure that a value appears at most once for the specified field. On multiple fields, unique indexes ensure that any given combination of the index key values appears at most once.
Single Field Example
The following example updates the Recipe
model's cuisine
field,
setting the unique
option to True
to create a unique single field index:
cuisine = models.CharField(max_length=200, unique=True)
Note
Setting the unique
option to True
automatically creates
an index on the given field.
Compound Example
The following example updates the Recipe
model's Meta
class to create
a compound index on the title
and cuisine
fields. The code
sets the constraints
option to a UniqueConstraint
instance, which
creates a unique compound index on these fields:
class Meta: db_table = "recipes" constraints = [ models.UniqueConstraint(fields=["title", "cuisine"], name="unique_regional_meal"), ]
Tip
Setting the constraints
option to a UniqueConstraint
automatically
creates an index on the specified fields. To learn more about the Meta
class's constraint
option, see Constraints
in the Django documentation.
Additional Information
To learn more about the index types mentioned in this guide, see the following MongoDB Server manual resources:
To learn more about creating indexes on Django models, see
Index
in the Django
documentation.