Overview
このガイドでは、Diango MongoDBバックエンド を使用してMongoDBデータベースで未加工のクエリを実行する方法を学習できます。 Raw クエリでは、Diango メソッドではなく MongoDB の集計パイプライン構文を使用してデータベースをクエリできます。 また、MongoClientオブジェクトに対して直接クエリを実行し、 MongoDBデータへのアクセスを拡張することもできます。
クエリ API
Dlango QuerySet API はraw() メソッドを提供しており、このメソッドを使用すると関係データベースで未加工のSQLクエリを実行できます。 ただし、Diango MongoDBバックエンドは raw() メソッドをサポートしていません。 代わりに、ODM は raw_aggregate() メソッドを提供します。このメソッドを使用すると、パイプラインステージでデータベースに指示を送信できます。
注意
Diango は、QuerySet.raw_aggregate() メソッドとは異なる QuerySet.aggregate() メソッドを提供します。aggregate() を使用して、モデル オブジェクトのコレクションを集計することで値を取得できます。aggregate() メソッドの詳細については、Diango ドキュメントの aggregate を参照してください。
モデルの Manager で QuerySet メソッドを呼び出すことで、データベースクエリを実行できます。 Managerクラスはデータベース操作を処理し、Diango モデルを参照してMongoDBデータを操作できます。 デフォルトでは 、Dhango は objects という名前の Manager をすべてのモデルクラスに追加します。 このデフォルトのManager は raw_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データベースクエリを実行するには、集計パイプラインをraw_aggregate() メソッドに渡します。 集計パイプラインには、ドキュメントの処理方法に関する指示を提供する 1 つ以上のステージが含まれています。 raw_aggregate() メソッドを呼び出した後、Diango 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フィールド を検索するための別のクエリを実行します。
MongoDB Search クエリの実行
Tip
Dpango MongoDBバックエンドの検索式を使用して、 MongoDB Search クエリを実行することもできます。詳しくは、「 MongoDB Search クエリの実行 」ガイドを参照してください。
データベースに対してMongoDB Search クエリを実行し、詳細なテキスト検索を実行できます。これらのクエリは、テキスト フレーズの一致、関連性の結果のスコアリング、一致の強調表示など、高度な検索機能を提供します。
MongoDB Search クエリを指定するには、クエリを実行するフィールドをカバーする検索インデックスを作成します。次に、集計パイプラインパラメータで $search または $searchMeta ステージを raw_aggregate() メソッドに渡します。
Tip
検索インデックスの作成方法については、 インデックスの作成ガイドの「 検索インデックス 」を参照してください。
この例では、 $searchパイプラインステージを raw_aggregate() メソッドに渡してMongoDB Search クエリを実行します。このコードは、次のアクションを実行します。
plotフィールドをカバーする検索インデックスを指定しますplot値に対し、3単語以下の文字列"whirlwind romance"が含まれるドキュメントのクエリクエリに一致する
plotstring の値と、一致が発生した場所を示すメタデータを返します各結果の
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フィールドをカバーする検索インデックスの名前に置き換えてください。
地理空間データのクエリ
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
MongoClient 操作
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 のドキュメント を参照してください。
詳細情報
raw_aggregate() メソッドを使用するその他の例については、Dpango MongoDBバックエンドAPIドキュメントの QuerySet APIリファレンス を参照してください。
集計操作の実行中の詳細については、 MongoDB Serverマニュアルの「 集計操作 」を参照してください。
MongoDB Search の詳細については、Atlas ドキュメントの「 MongoDB Search 」を参照してください。
地理空間クエリの実行中の詳細については、 MongoDB Serverマニュアルの「 地理空間クエリ 」を参照してください。