Docs 菜单
Docs 主页
/ / /
Kotlin 协程
/ /

投影构建器

在此页面上

  • Overview
  • 样本文档和示例
  • 投影操作
  • 包含
  • Exclusion
  • 合并投影
  • 排除 _id
  • 投影数组元素匹配
  • 投影数组切片
  • 投影文本分数

在本指南中,您可以学习;了解如何在MongoDB Kotlin驾驶员中使用 构建者 指定 投影

MongoDB 支持字段投影,可指定在返回查询结果时包含和排除哪些字段。MongoDB 中的投影遵循一些基本规则:

  • 除非明确排除,否则 _id 字段始终包含在内

  • 指定要包含的字段将隐式排除 _id 字段以外的所有其他字段

  • 指定排除字段只会删除查询结果中的该字段

有关投影机制的更多信息,请参阅MongoDB Server文档中的“从查询中指南项目字段”指南。

Projections 类为所有 MongoDB 投影操作符提供静态工厂方法。每个方法都返回一个 BSON 类型的实例,您可以将其传递给任何需要投影的方法。

提示

为了简洁起见,您可以选择导入 Projections 的方法 class:

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 }
]
}

以下数据类用于表示collection中的文档:

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类构建这些操作的相关信息。

使用 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)

以下示例包括yeartype字段以及隐式的_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)

使用 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)

以下示例排除了temperaturestype字段:

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() 方法合并多个投影。

以下示例包括 yeartype 字段,不包括 _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)方法变体指定一个数组投影,该投影将包含与所提供的查询筛选条件匹配的数组的第一个元素。在检索到与查询筛选条件(如提供)匹配的所有文档后,会发生此筛选。

注意

无论有多少个匹配项,都只会包含与指定查询筛选器匹配的第一个元素。

以下示例投影 temperatures 数组的第一个元素,其中 avg 字段大于 10.1

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)

后退

索引构建器