返すフィールドを指定する
Overview
このガイドでは、MongoDB Kotlin ドライバーを使用して、読み取り操作から返されるドキュメントにどのフィールドが表示されるかを制御する方法を学習できます。
多くの読み取りリクエストは、ドキュメント内のフィールドのサブセットのみを必要とします。 たとえば、ユーザーを にログインさせる場合、プロファイル情報はすべて必要ではなく、ユーザー名だけが必要になる場合があります。 デフォルトでは、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 },
このデータは、次の Kotlin データ クラスを使用してモデル化されます。
data class Fruit( val id: Int, val name: String, val qty: Int, val rating: Int )
次のクエリでは、各ドキュメントのname
フィールドを返すようにプロジェクションを渡します。 結果は、 FruitName
Kotlin データ クラスを使用してモデル化されます。
data class FruitName( val id: Int? = null, val name: String ) // Return all documents with only the name field val filter = Filters.empty() val projection = Projections.fields( Projections.include(FruitName::name.name) ) val flowResults = collection.find<FruitName>(filter).projection(projection) flowResults.collect { println(it)}
FruitName(id=1, name=apples), FruitName(id=2, name=bananas), FruitName(id=3, name=oranges), FruitName(id=4, name=avocados)
プロジェクション ドキュメントでは、読み取り操作の結果に各ドキュメントのname
フィールドが含まれることを指定します。 その結果、このプロジェクションではqty
フィールドとrating
フィールドが暗黙的に除外されます。空のクエリフィルターを使用してこのプロジェクションをfind()
にチェーンすると、上記の結果が得られます。
このプロジェクションにはname
フィールドのみが明示的に含まれていたにもかかわらず、クエリは_id
フィールドも返しました。このフィールドは、データ クラスでid
と表されます。
_id
フィールドは特別なケースで、明示的に除外されない限り、すべてのクエリ結果に常に含まれます。 これは、 _id
フィールドが各ドキュメントの一意の識別子であり、クエリの構築に役立つプロパティであるためです。
_id
は、プロジェクションにおける相互に排他的な包含や除外動作の唯一の例外です。返されるドキュメントに_id
が存在しないようにしたい場合は、他のフィールドを明示的に含める場合でも、 _id
フィールドを明示的に除外できます。
data class FruitName( val id: Int? = null, val name: String ) // Return all documents with *only* the name field // excludes the id val filter = Filters.empty() val projection = Projections.fields( Projections.include(FruitName::name.name), Projections.excludeId() ) val flowResults = collection.find<FruitName>(filter).projection(projection) flowResults.collect { println(it)}
FruitName(name=apples), FruitName(name=bananas), FruitName(name=oranges), FruitName(name=avocados)
プロジェクション ドキュメントでは、読み取り操作の結果に各返されたドキュメントのname
フィールドを含めることを指定し、 _id
フィールドを除外する場合は を指定します。 その結果、このプロジェクションではqty
フィールドとrating
フィールドが暗黙的に除外されます。空のクエリフィルターを使用してこのプロジェクションをfind()
にチェーンすると、上記の結果が得られます。
また、プロジェクションに含めるフィールドを複数指定することもできます。
Tip
プロジェクションでフィールドを指定する順序によって、返される順序は変更されません。
プロジェクションに含める 2 つのフィールドを識別するこの例では、 FruitRating
Kotlin データ クラスを使用して次の結果が得られます。
data class FruitRating( val name: String, val rating: Int ) val filter = Filters.empty() val projection = Projections.fields( Projections.include(FruitRating::name.name, FruitRating::rating.name), Projections.excludeId() ) val flowResults = collection.find<FruitRating>(filter).projection(projection) flowResults.collect { println(it)}
FruitRating(name=apples, rating=3), FruitRating(name=bananas, rating=1), FruitRating(name=oranges, rating=2), FruitRating(name=avocados, rating=5)
その他のプロジェクション例については、「クエリから返されるプロジェクト フィールドに関する MongoDB マニュアル ページ 」を参照してください。