返すフィールドを指定する
Overview
このガイドでは、MongoDB Java ドライバーを使用して、読み取り操作から返されるドキュメントにどのフィールドが表示されるかを制御する方法を学習できます。
多くの読み取りリクエストは、ドキュメント内のフィールドのサブセットのみを必要とします。 たとえば、ユーザーを にログインさせる場合、プロファイル情報はすべて必要ではなく、ユーザー名だけが必要になる場合があります。 デフォルトでは、MongoDB のクエリは一致するドキュメント内のすべてのフィールドを返します。 プロジェクションを使用して、必要なデータのみを返すことができます。
プロジェクションは、返されるドキュメントのどのフィールドを MongoDB に指示するドキュメントです。 プロジェクション ドキュメントを作成するには、 Projectionsクラスを使用します。
動作
プロジェクションは、次の 2 つの方法で機能します。
フィールドを明示的に含める。 これには、指定されていないすべてのフィールドを暗黙的に除外するという副作用があります。
フィールドを暗黙的に除外します。 これには、指定されていないすべてのフィールドが暗黙的に含まれるという副作用があります。
これらの 2 つのプロジェクション方法は相互に排他的です。つまり、フィールドを明示的に含める場合は、フィールドを明示的に除外することはできません。また、その逆も同様です。
重要
_id
フィールドは、これらの仕組みの対象となります。 返されない場合は、 _id
フィールドを明示的に除外する必要があります。 含める特定のフィールドを指定した場合でも、 _id
フィールドを除外することができます。
説明
品種を説明するドキュメントを含む次のコレクションを考えてみましょう。
{ "_id": 1, "name": "apples", "qty": 5, "rating": 3 }, { "_id": 2, "name": "bananas", "qty": 7, "rating": 1 }, { "_id": 3, "name": "oranges", "qty": 6, "rating": 2 }, { "_id": 4, "name": "avocados", "qty": 3, "rating": 5 },
次のクエリでは、各ドキュメントのname
フィールドを返すようにプロジェクションを渡します。
// return all documents with *only* the name field Bson filter = Filters.empty(); Bson projection = Projections.fields(Projections.include("name")); collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc));
プロジェクション ドキュメントでは、読み取り操作の結果に各ドキュメントのname
フィールドが含まれることを指定します。 その結果、このプロジェクションではqty
フィールドとrating
フィールドが暗黙的に除外されます。このプロジェクションを空のクエリフィルターを使用してfind()
にチェーンすると、次の結果が得られます。
{ "_id": 1, "name": "apples" } { "_id": 2, "name": "bananas" } { "_id": 3, "name": "oranges" } { "_id": 4, "name": "avocados" }
このプロジェクションにはname
フィールドのみが明示的に含まれていたにもかかわらず、クエリは_id
フィールドも返しました。
_id
フィールドは特別なケースで、明示的に除外されない限り、すべてのクエリ結果に常に含まれます。 これは、 _id
フィールドが各ドキュメントの一意の識別子であり、クエリの構築に役立つプロパティであるためです。
movies
コレクションは、このプロパティが有用な理由を示す良い例です。リメイクや別個の映画でも映画のタイトルが再利用される場合があるため、特定の映画を参照するには一意の_id
値が必要です。
_id
は、プロジェクションにおける相互に排他的な包含や除外動作の唯一の例外です。返されるドキュメントに_id
が存在しないようにしたい場合は、他のフィールドを明示的に含める場合でも、 _id
フィールドを明示的に除外できます。
// return all documents with only the name field Bson filter = Filters.empty(); Bson projection = Projections.fields(Projections.include("name"), Projections.excludeId()); collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc));
プロジェクション ドキュメントでは、読み取り操作の結果に各返されたドキュメントのname
フィールドを含めることを指定し、 _id
フィールドを除外する場合は を指定します。 その結果、このプロジェクションではqty
フィールドとrating
フィールドが暗黙的に除外されます。このプロジェクションを空のクエリフィルターを使用してfind()
にチェーンすると、次の結果が得られます。
{ "name": "apples" } { "name": "bananas" } { "name": "oranges" } { "name": "avocados" }
また、プロジェクションに含めるフィールドを複数指定することもできます。
Tip
プロジェクションでフィールドを指定する順序によって、返される順序は変更されません。
Bson filter = Filters.empty(); Bson projection = Projections.fields(Projections.include("name", "rating"), Projections.excludeId()); collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc));
プロジェクションに含める 2 つのフィールドを識別するこの例では、次の結果が得られます。
{ "name": "apples", "rating": 3 } { "name": "bananas", "rating": 1 } { "name": "oranges", "rating": 2 } { "name": "avocados", "rating": 5 }
その他のプロジェクション例については、「クエリから返されるプロジェクト フィールドに関する MongoDB マニュアル ページ 」を参照してください。