プロジェクション ビルダ
項目一覧
Overview
このガイドでは、MongoDB Kotlin ドライバーで ビルダ を使用して プロジェクション を指定する方法を学びます。
MongoDB はフィールドプロジェクションをサポートしており、クエリから結果を返すときに含めるフィールドと除外するフィールドを指定します。 MongoDB のプロジェクションは、いくつかの基本的なルールに従います。
_id
フィールドは明示的に除外されない限り、常に含まれます含めるフィールドを指定すると、
_id
フィールドを除く他のすべてのフィールドが暗黙的に除外されます除外するフィールドを指定すると、クエリ結果内のそのフィールドのみが削除されます
プロジェクション メカニズムの詳細については、MongoDB Server ドキュメントの「 クエリから返されるプロジェクト フィールド 」ガイド を参照してください。
Projections
クラスは、すべての MongoDB プロジェクション演算子の静的ファクトリー メソッドを提供します。 各メソッドはBSON型のインスタンスを返します。このインスタンスは、プロジェクションを必要とする任意のメソッドに渡すことができます。
サンプル ドキュメントと例
次のセクションでは、 projection_builders
というサンプル コレクションに対してクエリとプロジェクション操作を実行する例を紹介します。 各セクションでは、 collection
という名前の変数を使用して、 projection_builders
コレクションのMongoCollection
インスタンスを参照します。
コレクションには、2018 年と 2019 年の月間平均温度を摂氏単位で表す次のドキュメントが含まれています。
{ "year" : 2018, "type" : "even number but not a leap year", "temperatures" : [ { "month" : "January", "avg" : 9.765 }, { "month" : "February", "avg" : 9.675 }, { "month" : "March", "avg" : 10.004 }, { "month" : "April", "avg" : 9.983 }, { "month" : "May", "avg" : 9.747 }, { "month" : "June", "avg" : 9.65 }, { "month" : "July", "avg" : 9.786 }, { "month" : "August", "avg" : 9.617 }, { "month" : "September", "avg" : 9.51 }, { "month" : "October", "avg" : 10.042 }, { "month" : "November", "avg" : 9.452 }, { "month" : "December", "avg" : 9.86 } ] }, { "year" : 2019, "type" : "odd number, can't be a leap year", "temperatures" : [ { "month" : "January", "avg" : 10.023 }, { "month" : "February", "avg" : 9.808 }, { "month" : "March", "avg" : 10.43 }, { "month" : "April", "avg" : 10.175 }, { "month" : "May", "avg" : 9.648 }, { "month" : "June", "avg" : 9.686 }, { "month" : "July", "avg" : 9.794 }, { "month" : "August", "avg" : 9.741 }, { "month" : "September", "avg" : 9.84 }, { "month" : "October", "avg" : 10.15 }, { "month" : "November", "avg" : 9.84 }, { "month" : "December", "avg" : 10.366 } ] }
次のデータクラスは、コレクション内のドキュメントを表すために使用されます。
data class YearlyTemperature( val id: ObjectId, val year: Int, val type: String, val temperatures: List<MonthlyTemperature> ) { data class MonthlyTemperature( val month: String, val avg: Double ) }
プロジェクション操作
次のセクションには、利用可能なプロジェクション操作と、 Projections
クラスを使用してそれらを構築する方法に関する情報が記載されています。
包含
1 つ以上のフィールドを含めるように指定するには、 include()
メソッドを使用します。
次の例には、 year
フィールドと暗黙的に_id
フィールドが含まれています。
data class Results( val id: ObjectId, val year: Int) val filter = Filters.empty() val projection = Projections.include(YearlyTemperature::year.name) val resultsFlow = collection.find<Results>(filter).projection(projection) resultsFlow.collect { println(it) }
Results(id=6467808db5003e6354a1ee22, year=2018) Results(id=6467808db5003e6354a1ee23, year=2019)
次の例には、 year
フィールドとtype
フィールド、および暗黙的に_id
フィールドが含まれています。
data class Results( val id: ObjectId, val year: Int, val type: String) val filter = Filters.empty() val projection = Projections.include(YearlyTemperature::year.name, YearlyTemperature::type.name) val resultsFlow = collection.find<Results>(filter).projection(projection) resultsFlow.collect { println(it) }
Results(id=646780e3311323724f69a907, year=2018, type=even number but not a leap year) Results(id=646780e3311323724f69a908, year=2019, type=odd number, can't be a leap year)
Exclusion
1 つ以上のフィールドの除外を指定するには、 exclude()
メソッドを使用します。
次の例では、 temperatures
フィールドが除外されています。
data class Results( val id: ObjectId, val year: Int, val type: String) val filter = Filters.empty() val projection = Projections.exclude(YearlyTemperature::temperatures.name) val resultsFlow = collection.find<Results>(filter).projection(projection) resultsFlow.collect { println(it) }
Results(id=6462976102c85b29a7bfc9d5, year=2018, type=even number but not a leap year) Results(id=6462976102c85b29a7bfc9d6, year=2019, type=odd number, can't be a leap year)
次の例では、temperatures
フィールドとtype
フィールドが除外されています。
data class Results( val id: ObjectId, val year: Int) val filter = Filters.empty() val projection = Projections.exclude(YearlyTemperature::temperatures.name, YearlyTemperature::type.name) val resultsFlow = collection.find<Results>(filter).projection(projection) resultsFlow.collect { println(it) }
Results(id=64629783d7760d2365215147, year=2018) Results(id=64629783d7760d2365215148, year=2019)
プロジェクションの組み合わせ
複数のプロジェクションを結合するには、 fields()
メソッドを使用します。
次の例には、 year
フィールドとtype
フィールドが含まれ、 _id
フィールドは除外されています。
data class Results(val year: Int, val type: String) val filter = Filters.empty() val projection = Projections.fields( Projections.include(YearlyTemperature::year.name, YearlyTemperature::type.name), Projections.excludeId() ) val resultsFlow = collection.find<Results>(filter).projection(projection) resultsFlow.collect { println(it) }
Results(year=2018, type=even number but not a leap year) Results(year=2019, type=odd number, can't be a leap year)
除外: _id
excludeId()
便利メソッドを使用して、 _id
フィールドの除外を指定します。
data class Results(val year: Int, val type: String, val temperatures: List<YearlyTemperature.MonthlyTemperature>) val filter = Filters.empty() val projection = Projections.excludeId() val resultsFlow = collection.find<Results>(filter).projection(projection) resultsFlow.collect { println(it) }
Results(year=2018, type=even number but not a leap year, temperatures=[MonthlyTemperature(month=January, avg=9.765), MonthlyTemperature(month=February, avg=9.675), MonthlyTemperature(month=March, avg=10.004), MonthlyTemperature(month=April, avg=9.983), MonthlyTemperature(month=May, avg=9.747), MonthlyTemperature(month=June, avg=9.65), MonthlyTemperature(month=July, avg=9.786), MonthlyTemperature(month=August, avg=9.617), MonthlyTemperature(month=September, avg=9.51), MonthlyTemperature(month=October, avg=10.042), MonthlyTemperature(month=November, avg=9.452), MonthlyTemperature(month=December, avg=9.86)]) Results(year=2019, type=odd number, can't be a leap year, temperatures=[MonthlyTemperature(month=January, avg=10.023), MonthlyTemperature(month=February, avg=9.808), MonthlyTemperature(month=March, avg=10.43), MonthlyTemperature(month=April, avg=10.175), MonthlyTemperature(month=May, avg=9.648), MonthlyTemperature(month=June, avg=9.686), MonthlyTemperature(month=July, avg=9.794), MonthlyTemperature(month=August, avg=9.741), MonthlyTemperature(month=September, avg=9.84), MonthlyTemperature(month=October, avg=10.15), MonthlyTemperature(month=November, avg=9.84), MonthlyTemperature(month=December, avg=10.366)])
配列要素一致のプロジェクション
elemMatch(String, Bson)
メソッド バリアントを使用して、指定されたクエリフィルターに一致する配列の最初の要素を含む配列プロジェクションを指定します。 このフィルタリングは、クエリフィルター(指定された場合)に一致するすべてのドキュメントが取得された後に発生します。
注意
一致の数に関係なく、指定されたクエリフィルターに一致する最初の要素のみが含まれます。
次の例えでは、 avg
フィールドが10.1
より大きいtemperatures
配列の最初の要素をプロジェクトします。
data class Results( val year: Int, val temperatures: List<YearlyTemperature.MonthlyTemperature>? ) val filter = Filters.empty() val projection = Projections.fields( Projections.include(YearlyTemperature::year.name), Projections.elemMatch( YearlyTemperature::temperatures.name, Filters.gt(YearlyTemperature.MonthlyTemperature::avg.name, 10.1) ) ) val resultsFlow = collection.find<Results>(filter).projection(projection) resultsFlow.collect { println(it) }
Results(year=2018, temperatures=null) Results(year=2019, temperatures=[MonthlyTemperature(month=March, avg=10.43)])
操作のクエリ部分で一致条件を指定した場合、 elemMatch(String)
メソッド バリアントを使用して、配列の最初の要素を含める位置プロジェクションを指定します。 クエリフィルターに一致するドキュメントのみが検索されます。
重要
MongoDB バージョン 4.4 以前では、指定された配列フィールドがクエリフィルターに表示される必要があります。 MongoDB 4.4 以降では、クエリフィルターに表示されない配列フィールドで位置プロジェクトを使用できます。
次の例えでは、 temperatures
配列の最初の要素をプロジェクションします。
data class Results( val year: Int, val temperatures: List<YearlyTemperature.MonthlyTemperature> ) val filter = Filters.gt( "${YearlyTemperature::temperatures.name}.${YearlyTemperature.MonthlyTemperature::avg.name}", 10.1 ) val projection = Projections.fields( Projections.include(YearlyTemperature::year.name), Projections.elemMatch(YearlyTemperature::temperatures.name) ) val resultsFlow = collection.find<Results>(filter).projection(projection) resultsFlow.collect { println(it) }
Results(year=2019, temperatures=[MonthlyTemperature(month=March, avg=10.43)])
配列スライスのプロジェクション
配列のスライスをプロジェクションするには、 slice()
メソッドを使用します。
次の例では、 temperatures
配列の最初の 6 つの要素をプロジェクションします。
data class Results(val temperatures: List<YearlyTemperature.MonthlyTemperature>) val filter = Filters.empty() // First half of the year val projection = Projections.fields( Projections.slice(YearlyTemperature::temperatures.name, 6), Projections.excludeId() ) val resultsFlow = collection.find<Results>(filter) .projection(projection) resultsFlow.collect { println(it) }
Results(temperatures=[MonthlyTemperature(month=January, avg=9.765), MonthlyTemperature(month=February, avg=9.675), MonthlyTemperature(month=March, avg=10.004), MonthlyTemperature(month=April, avg=9.983), MonthlyTemperature(month=May, avg=9.747), MonthlyTemperature(month=June, avg=9.65)]) Results(temperatures=[MonthlyTemperature(month=January, avg=10.023), MonthlyTemperature(month=February, avg=9.808), MonthlyTemperature(month=March, avg=10.43), MonthlyTemperature(month=April, avg=10.175), MonthlyTemperature(month=May, avg=9.648), MonthlyTemperature(month=June, avg=9.686)])
次の例では、 temperatures
配列の最初の 6 つの要素をスキップし、次の6つのプロジェクションをプロジェクションします。
data class Results(val temperatures: List<YearlyTemperature.MonthlyTemperature>) val filter = Filters.empty() // Second half of the year val projection = Projections.fields( Projections.slice(YearlyTemperature::temperatures.name, 6, 6), Projections.excludeId() ) val resultsFlow = collection.find<Results>(filter) .projection(projection) resultsFlow.collect { println(it) }
Results(temperatures=[MonthlyTemperature(month=July, avg=9.786), MonthlyTemperature(month=August, avg=9.617), MonthlyTemperature(month=September, avg=9.51), MonthlyTemperature(month=October, avg=10.042), MonthlyTemperature(month=November, avg=9.452), MonthlyTemperature(month=December, avg=9.86)]) Results(temperatures=[MonthlyTemperature(month=July, avg=9.794), MonthlyTemperature(month=August, avg=9.741), MonthlyTemperature(month=September, avg=9.84), MonthlyTemperature(month=October, avg=10.15), MonthlyTemperature(month=November, avg=9.84), MonthlyTemperature(month=December, avg=10.366)])
テキスト スコアのプロジェクション
テキストクエリのスコアのプロジェクションを指定するには、 metaTextScore()
メソッドを使用します。
次の例では、テキスト スコアをscore
フィールドの値としてプロジェクションします。
data class Results(val year: Int, val score: Double) val filter = Filters.text("even number") val projection = Projections.fields( Projections.include(YearlyTemperature::year.name), Projections.metaTextScore("score") ) val resultsFlow = collection.find<Results>(filter).projection(projection) resultsFlow.collect { println(it) }
Results(year=2018, score=1.25) Results(year=2019, score=0.625)