Docs Menu
Docs Home
/ / /
Kotlin コルーチン
/ /

プロジェクション ビルダ

項目一覧

  • Overview
  • サンプル ドキュメントと例
  • プロジェクション操作
  • 包含
  • Exclusion
  • プロジェクションの組み合わせ
  • 除外: _id
  • 配列要素一致のプロジェクション
  • 配列スライスのプロジェクション
  • テキスト スコアのプロジェクション

このガイドでは、MongoDB Kotlin ドライバーで ビルダ を使用して プロジェクション を指定する方法を学びます。

MongoDB はフィールドプロジェクションをサポートしており、クエリから結果を返すときに含めるフィールドと除外するフィールドを指定します。 MongoDB のプロジェクションは、いくつかの基本的なルールに従います。

  • _idフィールドは明示的に除外されない限り、常に含まれます

  • 含めるフィールドを指定すると、 _idフィールドを除く他のすべてのフィールドが暗黙的に除外されます

  • 除外するフィールドを指定すると、クエリ結果内のそのフィールドのみが削除されます

プロジェクション メカニズムの詳細については、MongoDB Server ドキュメントの「 クエリから返されるプロジェクト フィールド 」ガイド を参照してください。

Projectionsクラスは、すべての MongoDB プロジェクション演算子の静的ファクトリー メソッドを提供します。 各メソッドはBSON型のインスタンスを返します。このインスタンスは、プロジェクションを必要とする任意のメソッドに渡すことができます。

Tip

簡潔にするために、プロジェクション クラスのメソッドをインポートすることを選択できます。

import com.mongodb.client.model.Projections.*

次のセクションでは、 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(
@BsonId 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(@BsonId 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(@BsonId 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)

1 つ以上のフィールドの除外を指定するには、 exclude()メソッドを使用します。

次の例では、 temperaturesフィールドが除外されています。

data class Results(@BsonId 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(@BsonId 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)

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)

戻る

Indexes