Overview
在本指南中,您可以学习;了解如何使用 Django 模型创建MongoDB索引。索引可提高查询效率并提供额外的查询和文档存储功能。
如果没有索引, MongoDB必须扫描集合中的每个文档,以查找与查询匹配的文档。 这些集合扫描很慢,可能会对应用程序的性能产生负面影响。 但是,如果查询存在适当的索引, MongoDB就可以使用该索引来限制其检查的文档。
Django 提供了 Index 类,您可以使用该类在模型上创建索引。 Django MongoDB后端在模型表示的MongoDB集合上创建相同的索引。
提示
要学习;了解有关 Index 类的更多信息,请参阅 Django 文档中的 Index。
样本数据
本指南中的示例使用 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 模型映射到名为 recipes 的MongoDB集合。要学习;了解如何创建使用模型与MongoDB集合交互的 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 选项,对嵌入式文档中的字段索引。
高级索引配置
本节介绍如何创建以下高级索引类型:
警告
搜索索引迁移
创建新的MongoDB Search 或 Vector Search 索引并运行数据库迁移命令后,Django 可能需要一些时间来应用迁移。为了确保数据一致性,在MongoDB完成索引操作之前,Django 会进行阻塞。迁移可能需要几秒钟或几分钟才能完成,具体取决于集合的大小。
搜索索引
MongoDB Search 索引指定MongoDB Search查询的行为,MongoDB Search 查询是对MongoDB集合的全文搜索。
要创建搜索索引,请将模型的 Meta 类中的 indexes 选项分配给 SearchIndex对象。按任意顺序将以下参数传递给 SearchIndex() 构造函数:
fields:要索引的字段。name:(可选)搜索索引的名称。如果不指定此参数,Django 将自动生成索引名称。
从 Django MongoDB后端 v5.2.2 开始,您还可以将以下参数传递给 SearchIndex():
field_mappings:(可选)将字段名称映射到索引选项的字典。您可以使用此参数而不是fields来创建复杂搜索索引,以指定各个字段的索引行为。analyzer:(可选)在索引时应用字符串字段的分析器。如果不指定此参数, MongoDB Server默认为lucene.standard。search_analyzer:(可选)应用查询文本的分析器。如果未指定此参数,则其值与analyzer值相同。如果省略这两个参数, MongoDB Server默认为lucene.standard。
提示
要学习;了解有关MongoDB Search 查询和索引的更多信息,请参阅以下资源:
Django MongoDB后端API文档中的 SearchIndex 类
基本搜索索引示例
以下示例更新 Recipe 模型的 Meta 类,以在 title字段上创建名为 "title_search_idx" 的基本搜索索引:
class Meta: db_table = "recipes" indexes = [ SearchIndex( fields=["title"], name="title_search_idx", ) ]
高级搜索索引示例
以下示例创建一个搜索索引,将 cuisine字段索引为 token 类型,并将分析器设置为 lucene.simple:
class Meta: db_table = "recipes" indexes = [ SearchIndex( name="cuisine_search_idx", field_mappings={ "cuisine": { "type": "token" } }, analyzer="lucene.simple" ) ]
提示
要学习;了解有关上示例中搜索索引配置的更多信息,请参阅Atlas文档中的以下资源:
向量搜索索引
MongoDB Vector Search 索引允许您根据数据的语义而不是关键字匹配来查询数据。您可以将向量搜索与全文搜索查询和AI框架集成,以支持范围使用案例。
要创建向量搜索索引,请将模型的 Meta 类中的 indexes 选项分配给 VectorSearchIndex对象。按任意顺序将以下参数传递给 VectorSearchIndex() 构造函数:
name:(可选)向量搜索索引的名称。如果不指定此参数,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"], ) ]
提示
要学习;了解有关 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"), ]
提示
将 constraints 选项设置为 UniqueConstraint 会自动在指定字段上创建索引。要学习;了解有关 Meta 类的 constraint 选项的更多信息,请参阅 约束 Django 文档中的约束。
更多信息
要学习;了解有关本指南中提及的索引类型的更多信息,请参阅以下MongoDB Server手册资源:
要学习;了解有关在 Django 模型上创建索引的更多信息,请参阅 Django 文档中的 Index。