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()
方法的更多信息,请参阅 Django 文档中的 aggregate
。
您可以通过对模型的 Manager
调用 QuerySet
方法来运行数据库查询。 Manager
类处理数据库操作,并允许您通过引用 Django 模型与MongoDB数据交互。 默认情况下,Django 会向每个模型类添加一个名为 objects
的 Manager
。 此默认Manager
不支持raw_aggregate()
方法。 要使用此特定于MongoDB的方法,请将模型的 objects
字段设立为名为 MongoManager
的自定义管理器。
样本数据
本指南中的示例使用 Movie
和 Theater
模型,它们表示来自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
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应用程序,请访问入门教程。
运行原始查询
要运行原始数据库查询,请将聚合管道传递给 raw_aggregate()
方法。 聚合管道包含一个或多个阶段,提供有关如何进程文档的说明。 调用 raw_aggregate()
方法后,Django MongoDB后端将您的管道传递给 pymongo.collection.Collection.aggregate()
方法,并将查询结果作为模型对象返回。
本部分介绍如何使用 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")
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
阶段省略的字段。 在前面的示例中,查询检索 title
和 released
字段。 打印声明运行单独的查询来检索plot
字段。
运行 Atlas Search 查询
提示
您还可以使用 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()
方法对包含地理空间数据的字段运行查询。 地理空间数据表示地球表面或欧几里得平面上的位置。
要运行地理空间查询,请在包含地理空间数据的字段上创建 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}")
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
MongoClient 操作
如果要运行QuerySet
API和 raw_aggregate()
方法均未提供的数据库操作,可直接对 MongoClient
进行操作。 使用 MongoClient
时,您可以访问权限PyMongo驱动程序的数据库操作。 使用以下语法公开 MongoClient
:
from django.db import connections client = connections["<DATABASES key>"].database.client
将 "<DATABASES key>"
占位符替换为 DATABASES
字典中与目标数据库对应的键。 要使用默认数据库,请将占位符替换为 "default"
。
更多信息
要查看使用raw_aggregate()
方法的更多示例,请参阅 Django MongoDB后端API文档中的 QuerySet API参考。
要学习;了解有关运行聚合操作的更多信息,请参阅MongoDB Server手册中的聚合操作。
要学习;了解有关Atlas Search 的更多信息,请参阅Atlas文档中的Atlas Search 。