Overview
在本指南中,您可以学习;了解如何使用 Django 模型创建MongoDB索引。索引可提高查询效率并提供额外的查询和文档存储功能。
如果没有索引, MongoDB必须扫描集合中的每个文档,以查找与查询匹配的文档。 这些集合扫描很慢,可能会对应用程序的性能产生负面影响。 但是,如果查询存在适当的索引, MongoDB就可以使用该索引来限制其检查的文档。
Django 提供了 Index
类,您可以使用该类在模型上创建索引。 Django MongoDB后端在模型表示的MongoDB集合上创建相同的索引。
提示
要学习;了解有关Index
类的更多信息,请参阅Index
Django 文档中的 。
样本数据
本指南中的示例使用 Recipe
模型,其中包含嵌入式 Nutrition
模型作为其 nutrition
字段的值。 这些模型类具有以下定义:
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 from django_mongodb_backend.indexes import SearchIndex, VectorSearchIndex 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) ratings = ArrayField(models.IntegerField(default=0), size=10) nutrition = EmbeddedModelField(Nutrition, null=True, blank=True) class Meta: db_table = "recipes" def __str__(self): return self.title
在Recipe
模型的Meta
类中,db_table = "recipes"
选项指示 Django MongoDB后端将Recipe
模型映射到名为 的MongoDB集合。要学习;了解如何创建使用模型与MongoDB集合交互的recipes
Django应用程序,请访问 入门教程。
创建索引
要在模型上创建索引,请在模型的 Meta
类中指定 indexes
选项。 将此 indexes
选项的值设置为要创建的索引列表,如以下代码所示:
class Meta: indexes = [ models.Index(<first index definition>), models.Index(<second index definition>), # add more indexes here ]
要定义索引,请将以下参数传递给 models.Index()
方法:
fields
:指定要索引的字段列表。 此参数为必填项。name
:指定索引名称。 此参数是可选的,如果您未提供索引名称,则 Django 会自动创建一个索引名称。condition
:指定要索引的文档子集。 此参数是可选的。 要学习;了解有关condition
参数的更多信息,请参阅本指南的部分索引部分。
应用数据库迁移后,Django MongoDB后端会在MongoDB集合上创建相同的索引。
本节介绍如何创建以下索引类型:
单字段索引
单字段索引存储集合中单个字段的信息。 默认下,所有MongoDB集合在 _id
字段上都有一个索引。
以下示例更新 Recipe
模型的 Meta
类以在 title
字段上创建单字段索引,而 Django MongoDB后端会在 recipes
集合上创建该索引:
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["title"], name="title_idx"), ]
或者,您可以在模型的 title
字段上设立db_index
选项来创建索引,如以下代码所示:
class Recipe(models.Model): title = models.CharField(max_length=200, db_index=True)
复合索引
复合索引从集合中的多个字段收集数据并进行排序。 MongoDB按索引中指定的第一个字段对数据进行分组,然后按每个后续字段对数据进行分组。
以下示例更新 Recipe
模型的 Meta
类,以在 title
和 cook_time
字段上创建复合索引,而 MongoDB MongoDB后端会在 recipes
集合上创建该复合索引:
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["title", "cook_time"]), ]
Multikey Index
多键索引从大量字段收集数据并进行排序。 当您在大量字段上创建索引时, MongoDB会自动将该索引设置为多键索引。
以下示例更新 Recipe
模型的 Meta
类,以在 allergens
大量字段上创建复合索引,而 Django MongoDB后端会在 recipes
集合上创建该复合索引索引:
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["allergens"], name="allergy_idx"), ]
嵌入式文档索引
您可以在存储嵌入式模型值的字段上创建索引, MongoDB将其表示为嵌入式文档。
以下示例更新 Recipe
模型的 Meta
类,以在 nutrition
嵌入式模型字段上创建索引,而 MongoDB MongoDB后端会在 recipes
集合上创建该字段:
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["nutrition"]), ]
重要
上一示例中创建的索引仅用于指定整个嵌入式文档的查询。 对嵌入式文档中特定字段的查询不使用索引。 但是,您可以通过将内部 Meta
类添加到 Nutrition
模型并指定 indexes
选项,对嵌入式文档中的字段索引。
高级索引配置
本节介绍如何创建以下高级索引类型:
Atlas Search 索引
Atlas Search索引指定Atlas Search的行为,Atlas Search 是对MongoDB Atlas上托管的集合进行全文搜索。
要创建Atlas Search索引,请将模型的 Meta
类中的 indexes
选项分配给 SearchIndex
对象。将以下参数传递给 SearchIndex()
构造函数:
fields
:要索引的字段。name
:(可选) Atlas Search索引的名称。如果不指定此参数,Django 将自动生成索引名称。
以下示例更新 Recipe
模型的 Meta
类,以在 title
字段上创建名为 "title_search_idx"
的Atlas Search索引:
class Meta: db_table = "recipes" indexes = [ SearchIndex( fields=["title"], name="title_search_idx", ) ]
提示
要学习;了解有关Atlas Search查询和索引的更多信息,请参阅以下资源:
Django MongoDB后端API文档中的 SearchIndex 类。
Atlas Vector Search 索引
Atlas Vector Search索引允许您根据数据的语义含义而不是关键字匹配查询数据。您可以将向量搜索与全文搜索查询和AI框架集成,以支持范围使用案例。
要创建向量搜索索引,请将模型的 Meta
类中的 indexes
选项分配给 VectorSearchIndex
对象。将以下参数传递给 VectorSearchIndex()
构造函数:
name
: (可选) Atlas Vector Search索引的名称。如果不指定此参数,Django 将自动生成索引名称。fields
:要索引的字段。至少有一个字段必须是向量字段,由具有一定大小的FloatField
或IntegerField
值 组成的大量表示。similarities
:要使用的相似度函数。您可以使用"cosine"
、"dotProduct"
或"euclidean"
相似度函数。将函数指定为单个字符串值或值列表,将函数分配给各个向量字段。
以下示例更新 Recipe
模型的 Meta
类,以在 ratings
向量字段和 cook_time
数值字段上创建名为 "vector_search_idx"
的向量搜索索引:
class Meta: db_table = "recipes" indexes = [ VectorSearchIndex( name=["vector_search_idx"], fields=["ratings", "cook_time"], similarities=["cosine", "euclidean"], ) ]
提示
要学习;了解有关Atlas Vector Search查询和索引的更多信息,请参阅以下资源:
Django MongoDB后端API文档中的 VectorSearchIndex 类。
部分索引
部分索引仅对集合中符合指定过滤条件的文档索引,从而减少存储使用量和性能成本。
要创建部分索引,请将 condition
参数传递给 models.Index()
方法。 将条件值设置为包含过滤条件的 Q
对象。 使用 condition
参数时,您还必须将 name
参数传递给 models.Index()
。
提示
要学习;了解有关Q
对象的详情,请参阅 Django 文档中的Q
。
以下示例更新 Recipe
模型的 Meta
类以在 cuisine
字段上创建部分索引,指示 Django MongoDB后端仅对 cook_time
值小于 30
的文档索引:
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["cuisine"], condition=Q(cook_time__lt=30), name="fast_cuisine_idx"), ]
Unique Indexes
唯一索引可防止索引字段存储重复值。 在单个字段上,唯一索引可确保指定字段中的值最多出现一次。 在多个字段上,唯一索引可确保任何给定的索引键值组合最多出现一次。
单字段示例
以下示例更新 Recipe
模型的 cuisine
字段,将 unique
选项设置为 True
,以创建唯一的单字段索引:
cuisine = models.CharField(max_length=200, unique=True)
注意
将 unique
选项设置为 True
会自动在给定字段上创建索引。
复合示例
以下示例更新 Recipe
模型的 Meta
类,以在 title
和 cuisine
字段上创建复合索引。 代码将 constraints
选项设置为 UniqueConstraint
实例,这将在这些字段上创建唯一复合索引:
class Meta: db_table = "recipes" constraints = [ models.UniqueConstraint(fields=["title", "cuisine"], name="unique_regional_meal"), ]
更多信息
要学习;了解有关本指南中提及的索引类型的更多信息,请参阅以下MongoDB Server手册资源:
要学习;了解有关在 Django 模型上创建索引的更多信息,请参阅 Django 文档中的Index
。