对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

指定查询

在本指南中,您可以学习;了解如何使用 Django MongoDB后端来指定数据库查询。

您可以通过创建查询过滤来优化查询返回的文档设立。查询过滤是一个表达式,用于指定MongoDB在读取或写入操作中用于匹配文档的搜索条件。 在查询过滤中,您可以提示 Django MongoDB后端搜索与您的查询完全匹配的文档,也可以编写查询筛选器以Express更复杂的匹配条件。

Django QuerySet API提供了允许您检索模型对象的方法。 要运行MongoDB 数据库查询,请在模型管理器上调用 QuerySet 方法。 Manager 类处理数据库操作,并允许您通过引用 Django 模型与MongoDB数据交互。 默认情况下,Django 会向每个模型类添加一个名为 objects 的 Manager。

将 QuerySet 分配给变量时,在您评估该变量之前,Django MongoDB后端不会执行该操作。 对 QuerySet 求值后,Django 将查询结果保存在 QuerySet缓存中。 QuerySet 的未来评估将使用缓存的结果。

提示

要学习;了解有关 Django QuerySet API的详情,请参阅 Django 文档中的 QuerySet。

The examples in this guide use the Movie model, which represents the sample_mflix.movies collection from the Atlas sample datasets. The Movie model contains an embedded Award model as the value of its awards field. These model classes have the following definitions:

from django.db import models
from django_mongodb_backend.models import EmbeddedModel
from django_mongodb_backend.fields import EmbeddedModelField, ArrayField
class Award(EmbeddedModel):
wins = models.IntegerField(default=0)
nominations = models.IntegerField(default=0)
text = models.CharField(max_length=100)
class Movie(models.Model):
title = models.CharField(max_length=200)
plot = models.TextField(blank=True)
runtime = models.IntegerField(default=0)
released = models.DateTimeField("release date", null=True, blank=True)
awards = EmbeddedModelField(Award)
genres = ArrayField(models.CharField(max_length=100), null=True, blank=True)
imdb = models.JSONField(null=True)
class Meta:
db_table = "movies"
managed = False
def __str__(self):
return self.title

Movie 模型包括一个内部 Meta 类(用于指定模型元数据)和一个 __str__() 方法(用于定义模型的字符串表示形式)。 要学习;了解这些模型功能,请参阅创建模型指南中的定义模型。

您可以使用Python交互式Shell来运行代码示例。 要进入Shell ,请从项目的根目录运行以下命令:

python manage.py shell

进入Python Shell后,请确保导入以下模型和模块:

from <your application name>.models import Movie, Award
from django.utils import timezone
from datetime import datetime

要学习;了解如何创建使用Movie 模型和Python交互式Shell与MongoDB文档交互的 Django应用程序,请访问 Django MongoDB后端入门教程。

要查询MongoDB数据,请在模型管理器上调用 QuerySet 方法,并在查询过滤中指定匹配条件。

本部分介绍如何使用 QuerySet API中的以下方法:

要从集合中检索所有文档,请在模型管理器上调用 all() 方法。

以下示例调用 all() 方法来检索sample_mflix.movies集合中的所有文档:

Movie.objects.all()

要查询集合是否存在与一设立条件匹配的文档,请对模型管理器调用 filter() 方法。 将查询过滤传递给指定查询条件的 filter() 方法。

以下示例调用 filter() 方法来查询sample_mflix.movies集合中 runtime 值为 300 的文档:

Movie.objects.filter(runtime=300)

要从集合中检索一份文档,请在模型管理器上调用 get() 方法。 将查询过滤传递给指定查询条件的 get() 方法。

重要

如果您的查询不匹配任何文档或匹配多个文档,则 get() 方法会产生错误。 要从可能匹配多个文档的查询中检索一个文档,请使用 first() 方法。

以下示例调用 get() 方法来检索title 值为 "Finding Nemo" 的文档:

Movie.objects.get(title="Finding Nemo")

要查询集合是否有不符合搜索条件的文档,请对模型管理器调用 exclude() 方法。 将排除条件作为参数传递给 exclude() 方法。

以下示例调用 exclude() 方法从结果中排除 datetime(1980, 1, 1)(一月 1,1980)之前发布的文档:

Movie.objects.exclude(released__lt=timezone.make_aware(datetime(1980, 1, 1)))

提示

The preceding example uses the lt field lookup to query the collection. To learn more about comparison lookups, see the Use Comparison Lookups section in this guide.

如果要运行Django 的查询API不支持的复杂查询,可以使用 raw_aggregate() 方法。 此方法允许您在MongoDB聚合管道中指定查询条件,并将其作为参数传递给 raw_aggregate()。

要学习;了解如何运行原始数据库查询,请参阅执行原始数据库查询指南。

您可以在查询过滤中使用字段查找来进一步优化查询条件。字段查找可让您明确正在查询的字段与要查询的值之间的关系。 使用以下语法指定字段查找:

Model.objects.filter(<field name>__<lookup type>=<value>)

您可以使用不同的查找类型执行高级查询,例如部分文本匹配、大量元素查询、正则表达式匹配以及日期时间字段的年份值匹配。

提示

要查看查找类型的完整列表,请参阅 QuerySetDjango API参考中的字段查找。

本节介绍如何通过以下方式优化查询筛选器:

下表描述了可用于运行包含文本值的特定匹配条件的查询的一些查找类型:

查找类型
说明

exact

指定精确的文本匹配。如果您在查询筛选条件中未提供查询类型,Django MongoDB 后端 将默认使用此类型。

您可以通过使用 iexact 指定不区分大小写的精确文本匹配。

contains

指定部分文本匹配。

您可以使用 icontains 指定不区分大小写的部分文本匹配。

startswith

匹配以指定文本开头的字段值。

您可以使用 istartswith 指定不区分大小写的部分文本匹配。

endswith

匹配以指定文本结尾的字段值。

您可以使用 iendswith 指定不区分大小写的部分文本匹配。

以下示例使用 contains 查找来查询plot 值包含文本 "coming-of-age" 的文档:

Movie.objects.filter(plot__contains="coming-of-age")

下表描述了可用于运行根据指定值评估字段值的查询的部分查找类型:

查找类型
说明

gt

匹配大于指定值的字段值。

gte

匹配大于或等于指定值的字段值。

lt

匹配小于指定值的字段值。

lte

匹配小于或等于指定值的字段值。

以下示例使用 lte 查找来查询runtime 值小于或等于 50 的文档:

Movie.objects.filter(runtime__lte=50)

您可以通过以下方式运行使用多组匹配条件的查询:

  • 将多个查询筛选器传递给查询方法,用逗号分隔。要查看示例,请参阅 Django 文档中的检索对象。

  • 将查询方法链接在一起。要学习;了解更多信息,请参阅 Django 文档中的链接筛选器。

  • 使用 Q 对象,并用逻辑操作符分隔每个对象。要学习;了解更多信息,请参阅 Django 文档中的使用 Q 对象进行的复杂查找。

您可以使用 Q 对象来运行具有多组匹配条件的查询。 要创建 Q对象,请将查询过滤传递给 Q() 方法。 您可以将多个 Q 对象作为参数传递给查询方法,并用 OR (|)、AND (&) 或 XOR (^)操作符符分隔每个 Q对象。 您还可以通过在 Q 对象前加上 ~ 符号来取反。

此示例使用 Q 对象来查询满足以下查询条件的文档:

  • title 字段值以文本 "Funny" 或 "Laugh" 开头

  • genres 大量字段不包含值 "Comedy"

Movie.objects.filter(
(Q(title__startswith="Funny") | Q(title__startswith="Laugh"))
& ~Q(genres__contains=["Comedy"])
)

提示

前面的示例对 ArrayField 值使用了字段查找。有关查询 ArrayField 的更多信息,请参阅本指南中的“查询数组值”部分。

本节介绍如何通过以下方式修改查询结果:

您可以使用 order_by() 方法为查询结果提供排序顺序。 要指定根据给定字段的值进行升序排序,请将字段名称作为参数传递。 要指定降序排序,请将前缀为减号 (-) 的字段名称作为参数传递。

您可以将多个字段名称(以逗号分隔)传递给 order_by() 方法。 Django MongoDB后端按提供的顺序按每个字段对结果进行排序。

此示例将执行以下动作:

  • 在 Movie 模型管理器上调用 filter() 方法以查询sample_mflix.movies集合

  • 查询 title 值以文本 "Rocky" 开头的文档

  • 按 released字段值的升序对结果进行排序

Movie.objects.filter(title__startswith="Rocky").order_by("released")

您可以使用 Python 的数组切片语法指定查询返回的结果数,如以下代码所示:

Model.objects.filter(<query filter>)[<start>:<end>]

将 <start> 和 <end> 占位符替换为表示要返回的结果子集的整数值。 起始值不包括在内,结束值包括在内。

如果省略 <start> 值,则查询会返回从第一个匹配项开始的每个结果,直到返回 <end> 值指定的数字。

如果省略 <end> 值,查询将返回每个结果,但会跳过 <start> 指定的初始结果数。

此示例将执行以下动作:

  • 在 Movie 模型管理器上调用 filter() 方法以查询sample_mflix.movies集合

  • 查询 released 值为 datetime(2010, 7, 16) 的文档(7 月 16、2010)

  • 返回第三个和第四个结果

Movie.objects.filter(released=timezone.make_aware(datetime(2010, 7, 16)))[2:4]

要从可能匹配多个结果的查询中检索第一个结果,请将 first() 方法链接到 filter() 方法。 将查询过滤传递给指定查询条件的 filter() 方法。

以下示例调用 filter() 和 first() 方法在 sample_mflix.movies集合中查询genres 值为 ["Crime", "Comedy"] 的第一个文档:

Movie.objects.filter(genres=["Crime", "Comedy"]).first()

本节介绍如何对以下字段运行查询:

您可以在模型上运行查询嵌入式模型字段的操作。 要查询这些字段,请指定模型字段和每个嵌入式字段名称,并用双下划线 (__) 分隔,直到找到要查询的字段,如以下代码所示:

Model.objects.filter(<model field>__<embedded model field>=<value>)

You can also use field lookups to refine your embedded model query. Add your lookup type after the embedded model field you're querying, prefixed by double underscores.

此示例使用查找来查询嵌入在 Movie 模型中的 Award 模型。 此嵌入式模型表示 sample_mflix.movies集合中的 awards字段及其嵌套的 wins、nominations 和 text 字段。 以下代码查询 awards.wins 嵌套字段值大于 150 的文档:

Movie.objects.filter(awards__wins__gt=150)

您可以使用标准查询语法查询在 ArrayField 值中的数据。 Django MongoDB后端提供了用于查询 ArrayField 值的其他字段查找类型,如下表所述:

查找类型
说明

contains

Matches fields that store the provided value as a subset of their data. This ArrayField lookup overrides the contains lookup described in the Use Text Match Lookups section of this guide.

contained_by

匹配存储所提供值子集的字段。这种查找类型与 contains 相反。

overlap

匹配存储任何所提供值的字段。

len

匹配存储所提供值数量的字段。

以下示例使用 overlap 查找来查询genres字段包含 ["Adventure", "Family"]大量中的任何值的文档:

Movie.objects.filter(genres__overlap=["Adventure", "Family"])

提示

本部分中的示例使用“创建模型”指南的“存储嵌入式模型数组数据”部分中定义的模型类。

You can run operations on your model that query fields of an array of embedded models. These queries use the same syntax as described in the Query Embedded Model Values section:

Model.objects.filter(<model field>__<embedded model field>=<value>)

You can also use field lookups to refine your embedded model query. Add your lookup type after the embedded model field you're querying, prefixed by double underscores. However, you can only use the following lookup types to query an embedded field:

  • exact

  • iexact

  • in

  • gt

  • gte

  • lt

  • lte

重要

如果 EmbeddedModelArrayField 中嵌入的模型实例有自己的嵌入式大量字段,则无法查询这些嵌套字段值。

You can use the len lookup type to filter by the number of embedded model instances in an EmbeddedModelArrayField value. To further refine your query, you can combine the len lookup with other comparison lookups.

此示例使用 len 查找来查询cast字段,该字段存储嵌入式 Actor 模型的大量。以下代码查询 cast大量长度大于 5 的文档:

Movie.objects.filter(cast__len__gt=5)

您可以使用索引和切片转换来查询EmbeddedModelArrayField 的特定大量元素。

以下示例指定一个大量索引,以查询其中 cast大量第一个元素的 last_name 值为 "Winslet" 的文档:

Movie.objects.filter(cast__0__last_name="Winslet")

同样,以下示例使用切片转换来查询cast大量的前三个元素之一的 last_name 值为 "Winslet" 的文档:

Movie.objects.filter(cast__0_2__last_name="Winslet")

要查询存储在 PolymorphicEmbeddedModelField 值中的数据,请使用前面的“查询嵌入式模型值”部分中描述的相同语法。您可以查询在嵌入式模型之间共享的字段或特定模型特有的字段。

重要

避免字段名称冲突

如果查询在多个嵌入式模型之间共享但具有不同数据类型的字段,则可能会看到不准确的结果。Django 无法正确确定为查找值分配哪种数据类型。在这种情况下,Django MongoDB后端会遍历嵌入式模型,并使用它找到的第一个字段和相应的数据类型。

同样,如果您查询在多个模型中具有相同名称和数据类型的嵌套嵌入式模型字段,则 Django MongoDB后端仅查询 PolymorphicEmbeddedModelField 定义中列出的第一个模型。

提示

以下示例使用“创建模型”指南的“存储多态嵌入式模型数据”部分中定义的模型类。

此示例使用查找来查询awards字段,该字段可以存储类型为 Oscar 或 GoldenGlobe 的嵌入式模型。该代码查询 awards.wins 值为 10 的文档,它可以匹配由任一嵌入式模型类型表示的文档:

Movie.objects.filter(awards__wins=10)

您还可以查询嵌入式模型之间未共享的字段。以下示例查询 awards.best_picture字段,该字段是 Oscar 嵌入式模型特有的:

Movie.objects.filter(awards__best_picture=True)

要查询存储在 PolymorphicEmbeddedModelArrayField 值中的数据,请使用查询嵌入式模型数组值部分中描述的相同语法和操作符。您可以查询在嵌入式模型之间共享的字段或特定模型特有的字段。

重要

避免字段名称冲突

如果查询在多个嵌入式模型之间共享但具有不同数据类型的字段,则可能会看到不准确的结果。Django 无法正确确定为查找值分配哪种数据类型。在这种情况下,Django MongoDB后端会遍历嵌入式模型,并使用找到的第一个字段和相应的数据类型。

同样,如果您查询在多个模型中具有相同名称和数据类型的嵌套嵌入式模型字段,则 Django MongoDB后端仅查询 PolymorphicEmbeddedModelArrayField 定义中列出的第一个模型。

提示

以下示例使用“创建模型”指南的“存储多态嵌入式模型数组数据”部分中定义的模型类。

此示例使用查找来查询awards字段,该字段存储类型为 Oscar 或 GoldenGlobe 的嵌入式模型的大量。该代码查询 awards.year 值小于 2000 的文档,这可以匹配任一嵌入式模型类型表示的文档。

Movie.objects.filter(awards__year__lt=2000)

重要

适用于 v6.0.1

您只能在 Django MongoDB后端 v6.0.1 及更高版本中使用空间查找。

提示

GeoDjango 字段

在运行地理空间查询之前,必须创建一个包含 GeoDjango 字段的模型。要学习了解如何指定这些字段,请参阅《地理空间数据建模》指南。

您可以使用空间查找来查询存储地理空间数据的 GeoDjango 字段。Django MongoDB后端支持以下空间查找:

  • contains:查询包含指定查找几何图形的值,您必须在 Point对象中指定该几何图形

  • disjoint:查询与查找几何在空间上不相交或不相交的值

  • distance_gt:查询与查找几何图形的距离大于指定距离值的值

  • distance_lte:查询与查找几何图形的距离小于或等于指定距离值的值

  • dwithin:查询与查找几何图形的距离在指定距离值范围内的值

  • intersects:查询与查找几何图形在空间上相交的值

  • within:查询空间上位于查找几何图形边界内的值

要学习;了解有关这些查找的更多信息,请参阅 空间查找 Django 文档中的。

提示

要查看此示例中使用的示例模型,请参阅模型地理空间数据指南中的模型示例。

此示例使用 within 空间查找来查询Theater 模型,该模型包含存储地理空间数据的嵌入式 Location 模型。此代码将查询曼哈顿范围内具有 location.geo 个字段值的文档:

from django.contrib.gis.geos import Polygon
manhattan_coords = [
[-73.925492, 40.877410],
[-73.910372, 40.872366],
[-73.935127, 40.834020],
[-73.929049, 40.798569],
[-73.976485, 40.711432],
[-74.015747, 40.701229],
[-74.018859, 40.708367],
[-74.008007, 40.754307],
[-73.925492, 40.877410]
]
# Creates a polygon from the coordinates
search_area = Polygon(manhattan_coords)
Theater.objects.filter(location__geo__within=search_area)

You can query data stored in a JSONField value by using the same syntax as show in the Query Embedded Model Values section. Chain each field and nested field name together, separated by double underscores (__), until you reach the field you want to query.

以下示例查询值为 JSONField 的 imdb字段,其嵌套 votes字段的值是否超过 900000:

Movie.objects.filter(imdb__votes__gt=900000)

您可以使用 KT() 表达式来注释和过滤JSONField 值中存储的数据。 KT() 表达式允许您在 JSONField 中处理键的文本值、索引或路径转换。 将 KT()表达式传递给 annotate() 方法,该方法使用提供的 KT() 表达式注释 QuerySet 中的每个对象。

提示

要学习;了解有关 KT() 表达式和 annotate() 方法的更多信息,请参阅 Django 文档中的以下资源:

以下示例使用 annotate() 和 KT() 创建新的 score 键,用于存储 imdb.rating 嵌套字段值。 然后,代码按 score 值降序对 sample_mflix.movies集合中的每个文档进行排序:

from django.db.models.fields.json import KT
Movie.objects.annotate(score=KT("imdb__rating")).all().order_by("-score")

您可以使用 pk 查找快捷方式来查询主键, MongoDB将其存储为 ObjectId 值。

以下示例将查询 sample_mflix.movies集合主键为 ObjectId("573a1394f29313caabce0d37") 的文档:

from bson import ObjectId
Movie.objects.get(pk=ObjectId("573a1394f29313caabce0d37"))

表示 sample_mflix.movies集合的Movie 模型使用 id字段作为其主键。 以下示例使用 id字段构造与上述代码相同的查询:

from bson import ObjectId
Movie.objects.get(id=ObjectId("573a1394f29313caabce0d37"))

要学习;了解如何使用 MongoDB 的聚合管道语法运行原始数据库查询,请参阅执行原始数据库查询指南。

要学习;了解如何执行其他QuerySet 操作,请参阅执行增删改查操作指南。

要学习;了解有关 Django 查询的更多信息,请参阅 Django 文档中的进行查询。