Overview
このガイドでは、Diango MongoDBバックエンド を使用してデータベースクエリを指定する方法を学習できます。
クエリフィルターを作成することで、クエリが返すドキュメントのセットを絞り込むことができます。クエリフィルターは、 MongoDB が読み取りまたは書込み (write)操作においてドキュメントを照合するために使用する検索条件を指定する式です。 クエリフィルターでは、Diango MongoDBバックエンド がクエリに完全に一致するドキュメントを検索するように要求することも、クエリフィルターを作成して、より複雑な一致条件をExpressこともできます。
クエリ API
Dlango QuerySet API には、モデル オブジェクトを検索できるメソッドが用意されています。 MongoDBデータベースクエリを実行するには、モデルのマネージャーで QuerySet メソッドを呼び出します。 Managerクラスはデータベース操作を処理し、Diango モデルを参照してMongoDBデータを操作できます。 デフォルトでは 、Dhango は objects という名前の Manager をすべてのモデルクラスに追加します。
変数に QuerySet を割り当てると、変数を評価するまで Diango MongoDBバックエンドは操作を実行しません。 QuerySet を評価した後、Diango はクエリ結果を QuerySetキャッシュに保存します。 QuerySet の将来の評価では、キャッシュされた結果が使用されます。
Tip
Django QuerySet APIの詳細については、Django ドキュメントの QuerySet を参照してください。
サンプル データ
このガイドの例では、AtlasサンプルデータセットMovie のsample_mflix.movies コレクションを表す モデルを使用します。Movie モデルには、awardsフィールドの値として埋め込み Award モデルが含まれています。 これらのモデル クラスには、次の定義があります。
from django.db import modelsfrom django_mongodb_backend.models import EmbeddedModelfrom django_mongodb_backend.fields import EmbeddedModelField, ArrayField
class Award(EmbeddedModel): wins = models.IntegerField(default=0) nominations = models.IntegerField(default=0) text = models.CharField(max_length=100)
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) awards = EmbeddedModelField(Award) genres = ArrayField(models.CharField(max_length=100), null=True, blank=True) imdb = models.JSONField(null=True)
class Meta: db_table = "movies" managed = False def __str__(self): return self.titleMovie モデルには、モデルメタデータを指定する内部 Metaクラスと、モデルの string 表現を定義する __str__() メソッドが含まれています。 これらのモデル機能の詳細については、「 モデルの作成ガイドの モデルの定義 」を参照してください。
コード例の実行
Pythonインタラクティブシェル を使用してコード例を実行できます。 シェルを入力するには、プロジェクトの ルートディレクトリから次のコマンドを実行します。
python manage.py shellPython シェルを入力したら、次のモデルとモジュールをインポートしていることを確認します。
from <your application name>.models import Movie, Awardfrom django.utils import timezonefrom datetime import datetimeモデルとPython対話型シェルMovie を使用してMongoDBドキュメントを操作する Dlangoアプリケーションを作成する方法については、「 Diango MongoDBバックエンドを使い始める 」チュートリアルをご覧ください。
クエリの実行
MongoDBデータをクエリするには、モデルのマネージャーで QuerySet メソッドを呼び出し、クエリフィルターで一致条件を指定します。
このセクションでは、 QuerySet APIから次のメソッドを使用する方法について説明します。
すべてのドキュメントを検索する
コレクションからすべてのドキュメントを取得するには、モデルのマネージャーで all() メソッドを呼び出します。
次の例では、 all() メソッドを呼び出して、sample_mflix.moviesコレクション内のすべてのドキュメントを検索します。
Movie.objects.all()一致するドキュメントの取得
一連の条件に一致するドキュメントをコレクションでクエリするには、モデルのマネージャーで filter() メソッドを呼び出します。 クエリ条件を指定するクエリフィルターを filter() メソッドに渡します。
次の例では、 filter() メソッドを呼び出して、sample_mflix.moviesコレクションで runtime の値が 300 であるドキュメントをクエリします。
Movie.objects.filter(runtime=300)Retrieve One Document
コレクションから 1 つのドキュメントを取得するには、モデルのマネージャーで get() メソッドを呼び出します。 クエリ条件を指定するクエリフィルターを get() メソッドに渡します。
重要
クエリが 1 ドキュメントまたは複数のドキュメントに一致しない場合、get() メソッドはエラーを生成します。 複数に一致する可能性のあるクエリから 1 つのドキュメントを検索するには、 first() メソッドを使用します。
次の例では、 get() メソッドを呼び出して、title の値が "Finding Nemo" であるドキュメントを 1 つ取得します。
Movie.objects.get(title="Finding Nemo")一致するドキュメントの除外
検索条件を満たさないドキュメントのコレクションをクエリするには、モデルのマネージャーで exclude() メソッドを呼び出します。 除外条件を引数として exclude() メソッドに渡します。
次の例では、 exclude() メソッドを呼び出して、datetime(1980, 1, 1) より前にリリースされたドキュメント(1、1980)を結果から除外します。
Movie.objects.exclude(released__lt=timezone.make_aware(datetime(1980, 1, 1)))Raw データベースクエリの実行
Dpango のクエリAPI がサポートしていない複雑なクエリを実行する場合は、raw_aggregate() メソッドを使用できます。 この方法を使用すると、 MongoDB集計パイプラインでクエリ条件を指定し、raw_aggregate() に引数として渡します。
クエリフィルターをカスタマイズする
クエリフィルターでフィールドルックアップ を使用することで、クエリ条件をさらに絞り込むことができます。フィールドルックを使用すると、クエリするフィールドとクエリ対象の値との関係を明確に行うことができます。 フィールドルックアップを指定するには、次の構文を使用します。
Model.objects.filter(<field name>__<lookup type>=<value>)さまざまなルックアップ タイプを使用して、日付時刻フィールドの部分テキスト一致、配列要素クエリ、正規式一致、年値一致などの高度なクエリを実行できます。
このセクションでは、クエリフィルターを次の方法で調整する方法について説明します。
テキスト一致検索の使用
次の表では、テキスト値の具体的な一致条件を含むクエリを実行するために使用できるいくつかのルックアップ タイプについて説明します。
ルックアップタイプ | 説明 |
|---|---|
| 正確なテキストの一致を指定します。クエリフィルターでルックアップタイプを指定しない場合、Django MongoDB Backend はデフォルトでこのタイプを使用します。
|
| 部分テキスト一致を指定します。
|
| 指定されたテキストで始まるフィールド値と一致します。
|
| 指定されたテキストで終わるフィールド値に一致します。
|
例
次の例では、 contains ルックアップを使用して、plot の値にテキスト "coming-of-age" が含まれるドキュメントをクエリします。
Movie.objects.filter(plot__contains="coming-of-age")比較検索の使用
次の表では、指定された値に対してフィールド値を評価するクエリを実行するために使用できるいくつかのルックアップ タイプについて説明します。
ルックアップタイプ | 説明 |
|---|---|
| 指定された値より大きいフィールド値と一致します。 |
| 指定された値以上のフィールド値と一致します。 |
| 指定値未満のフィールド値と一致します。 |
| 指定された値以下のフィールド値と一致します。 |
例
次の例では、 lte ルックアップを使用して、runtime の値が 50 以下のドキュメントをクエリします。
Movie.objects.filter(runtime__lte=50)組み合わせ検索
複数の一致条件のセットを使用するクエリは、次の方法で実行できます。
クエリメソッドに複数のクエリフィルターをカンマで区切って渡します。例を表示するには、Django ドキュメントのオブジェクトの取得を参照してください。
クエリ メソッドを連結します。詳細については、Diango ドキュメントのフィルターの連鎖を参照してください。
Qオブジェクトを使用し、各オブジェクトを 論理演算子で区切ります。詳細については、Dください ドキュメントの「 Q オブジェクトを使用した複雑な検索 」を参照してください。
Q オブジェクトの例
Q オブジェクトを使用して、一致条件の複数セットを持つクエリを実行できます。 Qオブジェクトを作成するには、クエリフィルターをQ() メソッドに渡します。 複数の Q オブジェクトをクエリ メソッドの引数として渡し、各 Qオブジェクトを OR(|)、AND(&)、または XOR(^)演算子で区切ります。 また、Q オブジェクトの前に ~ 記号を付けて、 オブジェクトを除外することもできます。
この例では、 Q オブジェクトを使用して、次のクエリ条件を満たすドキュメントをクエリします。
titleフィールド値は、テキスト"Funny"または"Laugh"のいずれかで始まるgenres配列フィールドに値が含まれていない"Comedy"
Movie.objects.filter( (Q(title__startswith="Funny") | Q(title__startswith="Laugh")) & ~Q(genres__contains=["Comedy"]))Tip
上記の例ではArrayField 値に対してフィールド検索を使用しています。ArrayField のクエリの詳細については、このガイドの「 配列値のクエリ 」セクションを参照してください。
クエリ結果の変更
このセクションでは、クエリ結果を次の方法で変更する方法について説明します。
結果を並べ替える
order_by() メソッドを使用して、クエリ結果の並べ替え順序を指定できます。 特定のフィールドの値に基づいて昇順の並べ替えを指定するには、フィールド名を引数として渡します。 降順のソートを指定するには、マイナス記号(-)を先頭に付けたフィールド名を引数として渡します。
カンマで区切られた複数のフィールド名を order_by() メソッドに渡すことができます。 Dlango MongoDBバックエンドは、指定された順序の各フィールドで結果をソートします。
例
この例では、次のアクションを実行します。
Movieモデルのマネージャーでfilter()メソッドを呼び出し、sample_mflix.moviesコレクションをクエリしますテキスト
"Rocky"で始まるtitle値を持つドキュメントをクエリします結果を
releasedフィールド値の昇順で並べ替えます
Movie.objects.filter(title__startswith="Rocky").order_by("released")結果をスキップして結果を制限する
次のコードに示すように、Python の 配列スケーリング構文 を使用して、クエリが返す結果の数を指定できます。
Model.objects.filter(<query filter>)[<start>:<end>]<start> と <end> のプレースホルダーを、返す結果のサブセットを表す整数値に置き換えます。 開始値は排他的で、終了値は包括的です。
<start> 値を省略すると、クエリは最初の一致から始めて、<end> 値で指定された数値が返されるまで、それぞれの結果を返します。
<end> 値を省略すると、クエリは各結果を返しますが、<start> で指定された初期結果の数はスキップされます。
例
この例では、次のアクションを実行します。
Movieモデルのマネージャーでfilter()メソッドを呼び出し、sample_mflix.moviesコレクションをクエリしますの
released値がdatetime(2010, 7, 16)であるドキュメントをクエリします(16、2010 年 7 月)3 番目と 4 番目の結果を返します
Movie.objects.filter(released=timezone.make_aware(datetime(2010, 7, 16)))[2:4]最初の結果を取得
複数の結果に一致する可能性のあるクエリから最初の結果を検索するには、first() メソッドを filter() メソッドに連鎖させます。 クエリ条件を指定するクエリフィルターを filter() メソッドに渡します。
次の例では、 filter() メソッドと first() メソッドを呼び出して、genres 値が ["Crime", "Comedy"] である最初のドキュメントを sample_mflix.moviesコレクションでクエリします。
Movie.objects.filter(genres=["Crime", "Comedy"]).first()高度なフィールドクエリ
このセクションでは、次のフィールドでクエリを実行する方法について説明します。
埋め込みモデル値のクエリ
埋め込みモデルのフィールドをクエリする操作をモデルに対して実行できます。 これらのフィールドをクエリするには、次のコードに示すように、クエリするフィールドに到達するまで、モデルフィールドと各埋め込みフィールド名を二重アンダースコア(__)で区切って指定します。
Model.objects.filter(<model field>__<embedded model field>=<value>)フィールドルックアップ を使用して埋め込みモデルクエリを改善することもできます。クエリする埋め込みモデルフィールドの後にルックアップ タイプを追加し、二重アンダースコアをプレフィックスとして付けます。
例
この例では、 lookup を使用して、Movie モデルに埋め込まれた Award モデルをクエリします。 この埋め込みモデルは、sample_mflix.moviesコレクション内の awardsフィールドと、そのネストされた wins、nominations、text フィールドを表します。 次のコードクエリは、awards.wins のネストされたフィールドの値が 150 より大きいドキュメントをクエリします。
Movie.objects.filter(awards__wins__gt=150)クエリ配列の値
標準のクエリ構文を使用して、ArrayField 値に保存されているデータをクエリできます。 Dlango MongoDBバックエンドは、ArrayField 値をクエリするための追加のフィールドルックアップ タイプを提供します。これについては次の表で説明します。
ルックアップタイプ | 説明 |
|---|---|
| 提供された値をデータのサブセットとして保存するフィールドと一致します。この |
| 提供された値のサブセットを保存するフィールドと一致します。このルックアップタイプは |
| 提供された値のいずれかを保存するフィールドと一致します。 |
| 提供された値の数を保存するフィールドと一致します。 |
例
次の例では、 overlap ルックアップを使用して、genresフィールドに ["Adventure", "Family"] 配列内の任意の値が含まれているドキュメントをクエリします。
Movie.objects.filter(genres__overlap=["Adventure", "Family"])埋め込みモデル配列値のクエリ
Tip
このセクションの例では、モデル作成ガイドの 埋め込みモデル配列データの保存 セクションで定義されたモデル クラスを使用します。
埋め込みモデルの配列のフィールドをクエリする操作をモデルに対して実行できます。これらのクエリは、埋め込みモデル値のクエリセクションで説明されているのと同じ構文を使用します。
Model.objects.filter(<model field>__<embedded model field>=<value>)フィールドルックアップ を使用して埋め込みモデルクエリを改善することもできます。クエリする埋め込みモデルフィールドの後にルックアップ タイプを追加し、二重アンダースコアをプレフィックスとして付けます。 ただし、埋め込みフィールドをクエリするには、次のルックアップ タイプのみを使用できます。
exactiexactingtgteltlte
重要
EmbeddedModelArrayField に埋め込まれたモデル インスタンスに独自の埋め込み配列フィールドがある場合、ネストされたフィールド値をクエリすることはできません。
長さ変換の例
len ルックアップ タイプを使用して、EmbeddedModelArrayField 値内の埋め込みモデルインスタンスの数でフィルタリングできます。クエリをさらに絞り込むには、len ルックアップを他の比較検索と組み合わせることができます。
この例では、len ルックアップを使用して、埋め込み Actor モデルの配列を保存する castフィールドをクエリします。次のコードでは、cast 配列の長さが 5 より大きいドキュメントをクエリします。
Movie.objects.filter(cast__len__gt=5)インデックスとスライスの変換例
インデックス変換とスライス変換を使用して、EmbeddedModelArrayField の特定の配列要素をクエリできます。
次の例では、cast 配列の最初の要素が last_name の値として "Winslet" であるドキュメントをクエリする配列インデックスを指定します。
Movie.objects.filter(cast__0__last_name="Winslet")同様に、次の例ではスライス変換を使用して、cast 配列の最初の 3 つの要素のうちの 1 つで、last_name 値が "Winslet" であるドキュメントをクエリします。
Movie.objects.filter(cast__0_2__last_name="Winslet")多形埋め込みモデル値のクエリ
PolymorphicEmbeddedModelField 値に保存されているデータをクエリするには、前述の埋め込みモデル値のクエリセクションで説明されているのと同じ構文を使用します。埋め込みモデル間で共有されるフィールドまたは特定のモデルに固有のフィールドをクエリできます。
重要
フィールド名の競合を避ける
複数の埋め込みモデル間で共有されているがデータ型が異なるフィールドをクエリすると、不正確な結果が表示される可能性があります。Dlango は、ルックアップ値に割り当てるデータ型を正しく決定できません。この場合、Diango MongoDBバックエンドは埋め込みモデルを反復処理し、最初に見つけたフィールドと対応するデータ型を使用します。
同様に、複数のモデルで同じ名前とデータ型を持つネストされた埋め込みモデルフィールドをクエリすると、Diango MongoDBバックエンドは PolymorphicEmbeddedModelField 定義にリストされている最初のモデルのみをクエリします。
例
Tip
次の例では、モデル作成ガイドの「多形埋め込みモデル データの保存」セクションで定義されたモデル クラスを使用します。
この例では、 lookup を使用して awardsフィールドには Oscar または GoldenGlobe タイプの埋め込みモデルが保存できます。このコードは、awards.wins 値が 10 であるドキュメントをクエリします。これは、次のいずれかの埋め込みモデル型で表されるドキュメントと一致します。
Movie.objects.filter(awards__wins=10)埋め込みモデル間で共有されていないフィールドをクエリすることもできます。次の例では、Oscar 埋め込みモデルに一意の awards.best_pictureフィールドをクエリします。
Movie.objects.filter(awards__best_picture=True)多形埋め込みモデル配列値のクエリ
PolymorphicEmbeddedModelArrayField 値に保存されているデータをクエリするには、「埋め込みモデル配列値のクエリ」セクションで説明されているものと同じ構文と演算子を使用します。埋め込みモデル間で共有されるフィールドまたは特定のモデルに固有のフィールドをクエリできます。
重要
フィールド名の競合を避ける
複数の埋め込みモデル間で共有されているがデータ型が異なるフィールドをクエリすると、不正確な結果が表示される可能性があります。Dlango は、ルックアップ値に割り当てるデータ型を正しく決定できません。この場合、Dhango MongoDBバックエンドは埋め込みモデルを反復処理し、最初に見つけたフィールドと対応するデータ型を使用します。
同様に、複数のモデルで同じ名前とデータ型を持つネストされた埋め込みモデルフィールドをクエリすると、Diango MongoDBバックエンドは PolymorphicEmbeddedModelArrayField 定義にリストされている最初のモデルのみをクエリします。
例
Tip
次の例では、モデル作成ガイドの「多形埋め込みモデル配列データの保存」セクションで定義されたモデル クラスを使用します。
この例では、 lookup を使用して awardsフィールドには Oscar または GoldenGlobe タイプの埋め込みモデルの配列が保存されます。このコードは、awards.year の値が 2000 より小さいドキュメントをクエリします。この値は、いずれかの埋め込みモデル型で表されるドキュメントと一致します。
Movie.objects.filter(awards__year__lt=2000)地理空間値のクエリ
重要
v6.0.1 で利用可能
空間検索は Diango MongoDBバックエンド v6.0.1 以降でのみ使用できます。
Tip
GeoDiango フィールド
地理空間クエリを実行中前に、GeoDiango フィールドを持つモデルを作成する必要があります。これらのフィールドを指定する方法については、モデル地理空間データのガイドを参照してください。
空間ルックアップを使用して、地理空間データを保存する GeoDiango フィールドをクエリできます。Dlango MongoDBバックエンド は次の空間検索をサポートしています。
contains: 指定したルックアップ ジオメトリを含む値をクエリします。これはPointオブジェクトで指定する必要がありますdisjoint: ルックアップ ジオメトリから空間的に離れた値、またはルックアップ ジオメトリと交差しない値のクエリdistance_gt: ルックアップジオメトリからの距離が指定された距離の値より大きい値をクエリしますdistance_lte: ルックアップ ジオメトリからの距離が指定された距離の値以下の値をクエリdwithin: ルックアップジオメトリからの距離が指定された距離値内にある値をクエリしますintersects: ルックアップ ジオメトリと空間的に交差する値のクエリwithin: ルックアップ ジオメトリの範囲内に空間的に存在する値をクエリします
これらの検索の詳細については、Dpango ドキュメントの空間検索を参照してください。
例
Tip
この例で使用されているサンプルモデルを表示するには、 「モデル地理空間データガイド」の 「モデル例」 を参照してください。
この例では、within 空間検索を使用して、地理空間データを保存する埋め込み Location モデルを含む Theater モデルをクエリします。コードは、manhattan の境界内に location.geoフィールド値を持つドキュメントをクエリします。
from django.contrib.gis.geos import Polygon
manhattan_coords = [ [-73.925492, 40.877410], [-73.910372, 40.872366], [-73.935127, 40.834020], [-73.929049, 40.798569], [-73.976485, 40.711432], [-74.015747, 40.701229], [-74.018859, 40.708367], [-74.008007, 40.754307], [-73.925492, 40.877410]]
# Creates a polygon from the coordinatessearch_area = Polygon(manhattan_coords)Theater.objects.filter(location__geo__within=search_area)Query JSON Values
JSONField「埋め込みモデル値のクエリ」セクションに示されているのと同じ構文を使用して、 値に保存されているデータをクエリできます。クエリするフィールドに到達するまで、各フィールドとネストされたフィールド名を二重アンダースコア(__)で区切って連結します。
次の例では、 JSONField の値を持つ imdbフィールドで、ネストされた votesフィールドの値が 900000 を超える値をクエリします。
Movie.objects.filter(imdb__votes__gt=900000)JSONデータの注釈とフィルタリング
KT() 式を使用して、JSONField 値に保存されているデータに注釈を付けてフィルタリングできます。 KT() 式を使用すると、JSONField 内でキー、インデックス、またはパス変換のテキスト値を操作できます。 KT()式をannotate() メソッドに渡します。これにより、QuerySet 内の各オブジェクトに、提供された KT() 式が注釈が付けられます。
次の例では、 annotate() と KT() を使用して新しい score キーを作成し、imdb.rating のネストされたフィールド値を保存します。 次に、コードは sample_mflix.moviesコレクション内の各ドキュメントをscore 値の降順でソートします。
from django.db.models.fields.json import KT
Movie.objects.annotate(score=KT("imdb__rating")).all().order_by("-score")プライマリキー値のクエリ
pk ルックアップ ショートカットを使用して、 MongoDB がObjectId 値として保存するプライマリキー値をクエリできます。
次の例では、プライマリキーが ObjectId("573a1394f29313caabce0d37") であるドキュメントを sample_mflix.moviesコレクションでクエリします。
from bson import ObjectId
Movie.objects.get(pk=ObjectId("573a1394f29313caabce0d37"))sample_mflix.moviesコレクションを表す Movie モデルは、idフィールドをプライマリキーとして使用します。 次の例では、 idフィールド を使用して、前のコードと同じクエリを構築します。
from bson import ObjectId
Movie.objects.get(id=ObjectId("573a1394f29313caabce0d37"))詳細情報
MongoDB の集計パイプライン構文 を使用して未加工のデータベースクエリを実行する方法については、「 Raw データベース クエリの実行 」ガイドを参照してください。
その他のQuerySet 操作を実行する方法については、 「 CRUD操作の実行 」ガイドを参照してください。
Diango クエリの詳細については、Diango ドキュメントのクエリの作成を参照してください。