Overview
在本指南中,您可以学习;了解如何使用 Django MongoDB后端对MongoDB 数据库运行原始查询。 原始查询允许您使用 MongoDB 的聚合管道语法而不是 Django 方法来查询数据库。 您还可以直接对 MongoClient对象运行查询,以扩展对MongoDB数据的访问权限。
查询 API
Django QuerySet API提供了 raw() 方法,允许您对关系数据库执行原始SQL查询。 但是,Django MongoDB后端不支持raw() 方法。 相反,ODM 提供了 raw_aggregate() 方法,您可以使用该方法在管道阶段向数据库发送指令。
注意
Django 提供了 QuerySet.aggregate() 方法,该方法不同于 QuerySet.raw_aggregate() 方法。您可以使用 aggregate() 通过聚合模型对象集合来检索值。要学习;了解有关 aggregate() 方法的更多信息,请参阅 aggregate Django 文档中的。
您可以通过对模型的 Manager 调用 QuerySet 方法来运行数据库查询。 Manager 类处理数据库操作,并允许您通过引用 Django 模型与MongoDB数据交互。 默认情况下,Django 会向每个模型类添加一个名为 objects 的 Manager。 此默认Manager 不支持raw_aggregate() 方法。 要使用此特定于MongoDB的方法,请将模型的 objects字段设立为名为 MongoManager 的自定义管理器。
样本数据
The examples in this guide use the Movie and Theater models, which represent collections in the sample_mflix database from the Atlas sample datasets. These models explicitly set the objects field to use a custom MongoManager, rather than Django's default Manager class. This guide also uses a Location embedded model to represent the Theater model's location field. The model classes have the following definitions:
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
Movie 和 Theater 模型包括一个内部 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应用程序,请访问 Django MongoDB后端入门教程。
运行原始查询
要运行原始数据库查询,请将聚合管道传递给 raw_aggregate() 方法。 聚合管道包含一个或多个阶段,提供有关如何进程文档的说明。 调用 raw_aggregate() 方法后,Django MongoDB后端将您的管道传递给 pymongo.collection.Collection.aggregate() 方法,并将查询结果作为模型对象返回。
提示
To learn more about constructing aggregation pipelines, see Aggregation Pipeline in the MongoDB Server manual.
本部分介绍如何使用 raw_aggregate() 方法执行以下任务:
筛选器和项目文档字段
此示例通过在 Movie 模型的 MongoManager 上调用 raw_aggregate() 方法来运行原始数据库查询,从而查询 sample_mflix.movies集合。 代码将以下聚合管道阶段传递给 raw_aggregate():
$match:筛选title字段值为"The Parent Trap"的文档$project:包括返回的模型对象的title和released字段
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")
注意
raw_aggregate() 方法返回延迟的模型实例,这意味着您可以按需加载 $project 阶段省略的字段。 在前面的示例中,查询检索 title 和 released 字段。 打印声明运行单独的查询来检索plot字段。
运行MongoDB搜索查询
提示
您还可以使用 Django MongoDB 后端的搜索表达式运行 MongoDB 搜索查询。要学习,了解更多信息,请参阅运行 MongoDB 搜索查询指南。
您可以对数据库运行 MongoDB 搜索查询,以执行细粒度的文本搜索。这些查询提供高级搜索功能,例如匹配文本短语、对结果的相关性进行评分以及突出显示匹配项。
要指定MongoDB搜索查询,请创建涵盖要查询的字段的搜索索引。然后,将聚合管道参数中的 $search 或 $searchMeta 阶段传递给 raw_aggregate() 方法。
提示
要学习了解如何创建搜索索引,请参阅创建索引指南中的搜索索引。
此示例通过将 $search 管道阶段传递给 raw_aggregate() 方法来运行 MongoDB 搜索查询。该代码执行以下操作:
指定涵盖
plot字段的搜索索引查询
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")
重要
运行前面的示例时,请确保将 <search-index-name> 占位符替换为涵盖 plot字段的搜索索引的名称。
查询地理空间数据
您可以使用 raw_aggregate() 方法对包含地理空间数据的字段运行查询。 地理空间数据表示地球表面或欧几里得平面上的位置。
要运行地理空间查询,请在包含地理空间数据的字段上创建 2d 或 2dsphere索引。 然后,将聚合管道参数中的以下查询运算符之一传递给 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}")
MongoClient 操作
如果要运行QuerySet API和 raw_aggregate() 方法均未提供的数据库操作,可直接对 MongoClient 进行操作。 使用 MongoClient 时,您可以访问权限PyMongo驱动程序的数据库操作。 使用以下语法公开 MongoClient:
from django.db import connections client = connections["<DATABASES key>"].database.client
将 "<DATABASES key>" 占位符替换为 DATABASES 字典中与目标数据库对应的键。 要使用默认数据库,请将占位符替换为 "default"。
提示
To learn how to use PyMongo to interact with MongoDB data, see the PyMongo documentation.
更多信息
要查看使用 raw_aggregate() 方法的更多示例,请参阅 Django MongoDB后端API文档中的 QuerySet API 参考。
To learn more about running aggregation operations, see Aggregation Operations in the MongoDB Server manual.
To learn more about MongoDB Search, see MongoDB Search in the Atlas documentation.
To learn more about running geospatial queries, see Geospatial Queries in the MongoDB Server manual.