Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs 菜单
Docs 主页
/ / /
Django MongoDB后端
/

执行原始数据库查询

在本指南中,您可以学习;了解如何使用 Django MongoDB后端对MongoDB 数据库运行原始查询。 原始查询允许您使用 MongoDB 的聚合管道语法而不是 Django 方法来查询数据库。 您还可以直接对 MongoClient对象运行查询,以扩展对MongoDB数据的访问权限。

Django QuerySet API提供了 raw() 方法,允许您对关系数据库执行原始SQL查询。 但是,Django MongoDB后端不支持raw() 方法。 相反,ODM 提供了 raw_aggregate() 方法,您可以使用该方法在管道阶段向数据库发送指令。

注意

Django 提供了 QuerySet.aggregate() 方法,该方法不同于 QuerySet.raw_aggregate() 方法。您可以使用 aggregate() 通过聚合模型对象集合来检索值。要学习;了解有关 aggregate() 方法的更多信息,请参阅 Django 文档中的 aggregate

您可以通过对模型的 Manager 调用 QuerySet 方法来运行数据库查询。 Manager 类处理数据库操作,并允许您通过引用 Django 模型与MongoDB数据交互。 默认情况下,Django 会向每个模型类添加一个名为 objectsManager。 此默认Manager 不支持raw_aggregate() 方法。 要使用此特定于MongoDB的方法,请将模型的 objects字段设立为名为 MongoManager 的自定义管理器。

本指南中的示例使用 MovieTheater 模型,它们表示来自Atlas示例数据集sample_mflix数据库中的集合。这些模型显式将 objects字段设立为使用自定义 MongoManager,而不是 Django 的默认Manager 类。本指南还使用 Location 嵌入式模型来表示 Theater 模型的位置字段。模型类具有以下定义:

from django.db import models
from django.contrib.gis.db import models
from django_mongodb_backend.fields import ArrayField, EmbeddedModelField
from django_mongodb_backend.models import EmbeddedModel
from django_mongodb_backend.managers import MongoManager
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)
genres = ArrayField(models.CharField(max_length=100), null=True, blank=True)
objects = MongoManager()
class Meta:
db_table = "movies"
managed = False
def __str__(self):
return self.title
class Location(EmbeddedModel):
address = models.JSONField(null=True)
geo = models.PointField()
class Theater(models.Model):
theaterId = models.IntegerField(default=0)
location = EmbeddedModelField(Location, null=True, blank=True)
class Meta:
db_table = "theaters"
managed = False
def __str__(self):
return self.theaterId

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

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

python manage.py shell

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

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

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

要运行原始数据库查询,请将聚合管道传递给 raw_aggregate() 方法。 聚合管道包含一个或多个阶段,提供有关如何进程文档的说明。 调用 raw_aggregate() 方法后,Django MongoDB后端将您的管道传递给 pymongo.collection.Collection.aggregate() 方法,并将查询结果作为模型对象返回。

提示

要学习;了解有关构建聚合管道的更多信息,请参阅MongoDB Server手册中的聚合管道。

本部分介绍如何使用 raw_aggregate() 方法执行以下任务:

此示例通过在 Movie 模型的 MongoManager 上调用 raw_aggregate() 方法来运行原始数据库查询,从而查询 sample_mflix.movies集合。 代码将以下聚合管道阶段传递给 raw_aggregate()

  • $match:筛选 title字段值为 "The Parent Trap" 的文档

  • $project:包括返回的模型对象的 titlereleased 字段

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.

注意

raw_aggregate() 方法返回延迟的模型实例,这意味着您可以按需加载 $project 阶段省略的字段。 在前面的示例中,查询检索 titlereleased 字段。 打印声明运行单独的查询来检索plot字段。

提示

您还可以使用 Django MongoDB后端的Atlas Search表达式运行Atlas Search查询。要学习;了解更多信息,请参阅运行Atlas Search查询指南。

您可以对数据库运行Atlas Search查询,以执行细粒度的文本搜索。 这些查询提供高级搜索功能,例如匹配文本短语、对结果的相关性进行评分以及突出显示匹配项。

要指定Atlas Search查询,请创建涵盖要查询的字段的Atlas Search索引。 然后,将聚合管道参数中的 $search$searchMeta 阶段传递给 raw_aggregate() 方法。

提示

要学习;了解如何创建Atlas Search索引,请参阅 创建索引指南中的Atlas Search索引

此示例通过将 $search管道阶段传递给 raw_aggregate() 方法来运行Atlas Search查询。 该代码执行以下操作:

  • 指定覆盖 plot字段的Atlas Search索引

  • 查询 plot 值包含字符串 "whirlwind romance" 且字符串之间的单词数不超过 3 个的文档

  • 返回与查询匹配的 plot 字符串值的部分以及指示匹配发生位置的元数据

  • 包括每个结果的 title字段和 highlight 或匹配文本

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'}]}]

重要

运行前面的示例时,请确保将 <search-index-name> 占位符替换为涵盖 plot字段的Atlas Search索引的名称。

您可以使用 raw_aggregate() 方法对包含地理空间数据的字段运行查询。 地理空间数据表示地球表面或欧几里得平面上的位置。

要运行地理空间查询,请在包含地理空间数据的字段上创建 2d2dsphere索引。 然后,将聚合管道参数中的以下查询运算符之一传递给 raw_aggregate() 方法:

  • $near

  • $geoWithin

  • $nearSphere

  • $geoIntersects

提示

Django MongoDB后端自动在 GeoDjango 字段上创建 2dsphere 索引,包括本指南的示例Location 模型中定义的 PointField。要学习;了解如何定义这些字段,请参阅《地理空间数据建模》指南。

此示例通过将 $match$geoWithin管道阶段传递给 raw_aggregate() 方法来运行地理空间查询。 该代码执行以下操作:

  • 指定表示芝加哥边界的坐标列表

  • 查询 location.geo字段存储芝加哥地区内位置的文档

  • 检索并打印芝加哥每个电影院的 theaterId

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

如果要运行QuerySet API和 raw_aggregate() 方法均未提供的数据库操作,可直接对 MongoClient 进行操作。 使用 MongoClient 时,您可以访问权限PyMongo驱动程序的数据库操作。 使用以下语法公开 MongoClient

from django.db import connections
client = connections["<DATABASES key>"].database.client

"<DATABASES key>" 占位符替换为 DATABASES 字典中与目标数据库对应的键。 要使用默认数据库,请将占位符替换为 "default"

提示

要学习;了解如何使用PyMongo与MongoDB数据交互,请参阅PyMongo文档。

要查看使用raw_aggregate() 方法的更多示例,请参阅 Django MongoDB后端API文档中的 QuerySet API参考。

要学习;了解有关运行聚合操作的更多信息,请参阅MongoDB Server手册中的聚合操作。

要学习;了解有关Atlas Search 的更多信息,请参阅Atlas文档中的Atlas Search

要学习;了解有关运行地理空间查询的更多信息,请参阅MongoDB Server手册中的地理空间查询。

后退

指定查询

在此页面上