Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs Menu
Docs Home
/ / /
Diango MongoDBバックエンド
/

Raw データベースクエリの実行

このガイドでは、Diango MongoDBバックエンド を使用してMongoDBデータベースで未加工のクエリを実行する方法を学習できます。 Raw クエリでは、Diango メソッドではなく MongoDB の集計パイプライン構文を使用してデータベースをクエリできます。 また、MongoClientオブジェクトに対して直接クエリを実行し、 MongoDBデータへのアクセスを拡張することもできます。

Dlango QuerySet API はraw() メソッドを提供しており、このメソッドを使用すると関係データベースで未加工のSQLクエリを実行できます。 ただし、Diango MongoDBバックエンドは raw() メソッドをサポートしていません。 代わりに、ODM は raw_aggregate() メソッドを提供します。このメソッドを使用すると、パイプラインステージでデータベースに指示を送信できます。

注意

Django provides a QuerySet.aggregate() method, which differs from the QuerySet.raw_aggregate() method. You can use aggregate() to retrieve values by aggregating a collection of model objects. To learn more about the aggregate() method, see aggregate in the Django documentation.

モデルの ManagerQuerySet メソッドを呼び出すことで、データベースクエリを実行できます。 Managerクラスはデータベース操作を処理し、Diango モデルを参照してMongoDBデータを操作できます。 デフォルトでは 、Dhango は objects という名前の Manager をすべてのモデルクラスに追加します。 このデフォルトのManagerraw_aggregate() メソッドをサポートしていません。 MongoDB固有のこのメソッドを使用するには、モデルの objectsフィールドをMongoManager と呼ばれるカスタム マネージャーに設定します。

このガイドの例では、Atlasサンプルデータセットsample_mflixデータベース内のコレクションを表す Movie モデルと Theater モデルを使用します。これらのモデルでは、Diango のデフォルトの Managerクラスではなく、カスタム MongoManager を使用するように objectsフィールドを明示的に設定します。このガイドでは、Theater モデルのロケーションフィールドを表すために、Location 埋め込みモデルも使用します。モデル クラスには、次の定義があります。

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クラスと、モデルの string 表現を定義する __str__() メソッドが含まれています。 これらのモデル機能について詳しくは、「 モデルの作成ガイドでモデルを定義する 」を参照してください。

Pythonインタラクティブシェル を使用してコード例を実行できます。 シェルを入力するには、プロジェクトの ルートディレクトリから次のコマンドを実行します。

python manage.py shell

Python シェルを入力したら、次のモデルとモジュールをインポートしていることを確認します。

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

Movie モデルとPython対話型シェル を使用してMongoDBドキュメントを操作する Dlangoアプリケーションを作成する方法については、使い始める チュートリアルをご覧ください。

Rawデータベースクエリを実行するには、集計パイプラインをraw_aggregate() メソッドに渡します。 集計パイプラインには、ドキュメントの処理方法に関する指示を提供する 1 つ以上のステージが含まれています。 raw_aggregate() メソッドを呼び出した後、Diango MongoDBバックエンドはパイプラインをpymongo.collection.Collection.aggregate() メソッドに渡し、クエリ結果をモデル オブジェクトとして返します。

Tip

集計パイプラインの構築の詳細については、 MongoDB Serverマニュアルの「 集計パイプライン 」を参照してください。

このセクションでは、raw_aggregate() メソッドを使用して次のタスクを実行する方法について説明します。

この例では、 Movie モデルの MongoManagerraw_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フィールド を検索するための別のクエリを実行します。

Tip

Dpango MongoDBバックエンドの Atlas Search 式 を使用して、Atlas Search クエリを実行することもできます。詳しくは、 「Atlas Search クエリの実行」ガイドを参照してください。

データベースに対して Atlas Search クエリを実行し、詳細なテキスト検索を実行できます。 これらのクエリは、テキスト フレーズの一致、関連性の結果のスコアリング、一致の強調表示など、高度な検索機能を提供します。

Atlas Search クエリを指定するには、クエリするフィールドをカバーする Atlas Searchインデックスを作成します。 次に、集計パイプラインパラメータで $search または $searchMeta ステージを raw_aggregate() メソッドに渡します。

Tip

Atlas Search インデックスの作成方法については、 インデックスの作成ガイドの「Atlas Search インデックス」を参照してください。

この例では、 $searchパイプラインステージを raw_aggregate() メソッドに渡して Atlas Search クエリを実行します。 このコードは、次のアクションを実行します。

  • plotフィールドをカバーする Atlas Searchインデックスを指定します

  • plot 値に対し、3 単語以下の文字列 "whirlwind romance" が含まれるドキュメントのクエリ

  • クエリに一致する plot string の値と、一致が発生した場所を示すメタデータを返します

  • 各結果の 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

Tip

Dlango MongoDBバックエンドは、このガイドのサンプルLocation モデルで定義されている PointField を含む GeoDjango フィールドに 2dsphere インデックスを自動的に作成します。これらのフィールドを定義する方法については、 モデル地理空間データガイド を参照してください。

この例では、 $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" に置き換えます。

Tip

PyMongo を使用してMongoDBデータを操作する方法については、 PyMongo のドキュメント を参照してください。

To view more examples that use the raw_aggregate() method, see QuerySet API Reference in the Django MongoDB Backend API documentation.

集計操作の実行中の詳細については、 MongoDB Serverマニュアルの「 集計操作 」を参照してください。

Atlas Search の詳細については、Atlas ドキュメントの「 Atlas Search 」を参照してください。

地理空間クエリの実行中の詳細については、 MongoDB Serverマニュアルの「 地理空間クエリ 」を参照してください。

戻る

クエリを指定する

項目一覧