Docs 菜单
Docs 主页
/ / /
java sync
/ /

投影构建器

在此页面上

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

在本指南中,您可以了解如何在 MongoDB Java 驱动程序中使用 构建器 指定 投影

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

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

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

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

在此处查找有关投影机制的更多信息

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

提示

为了简洁起见,可以选择静态导入投影类的方法:

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

以下各节包含可用投影操作以及使用Projections类构建这些操作的相关信息。

使用 include() 方法指定包含一个或多个字段。

以下示例包括 year 字段和(隐式的)_id 字段:

Bson filter = Filters.empty();
Bson projection = include("year");
collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc.toJson()));

以下代码显示此投影的输出:

{"_id": {"$oid": "6042edc9f2b56342164e0790"}, "year": 2018}
{"_id": {"$oid": "6042edc9f2b56342164e0791"}, "year": 2019}

以下示例包括 yeartype 字段以及(隐式的)_id 字段:

Bson filter = Filters.empty();
Bson projection = include("year", "type");
collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc.toJson()));

以下代码显示此投影的输出:

{"_id": {"$oid": "6042edc9f2b56342164e0790"}, "year": 2018, "type": "even number but not a leap year"}
{"_id": {"$oid": "6042edc9f2b56342164e0791"}, "year": 2019, "type": "odd number, can't be a leap year"}

使用 exclude() 方法指定排除一个或多个字段。

以下示例排除了 temperatures(温度)字段:

Bson filter = Filters.empty();
Bson projection = exclude("temperatures");
collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc.toJson()));

以下代码显示此投影的输出:

{"_id": {"$oid": "6042edc9f2b56342164e0790"}, "year": 2018, "type": "even number but not a leap year"}
{"_id": {"$oid": "6042edc9f2b56342164e0791"}, "year": 2019, "type": "odd number, can't be a leap year"}

以下示例排除了typetemperatures字段:

Bson filter = Filters.empty();
Bson projection = exclude("temperatures", "type");
collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc.toJson()));

以下代码显示此投影的输出:

{"_id": {"$oid": "6042edc9f2b56342164e0790"}, "year": 2018}
{"_id": {"$oid": "6042edc9f2b56342164e0791"}, "year": 2019}

使用 fields() 方法合并多个投影。

以下示例包括 yeartype 字段,不包括 _id 字段:

Bson filter = Filters.empty();
Bson projection = fields(include("year", "type"), exclude("_id"));
collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc.toJson()));

以下代码显示此投影的输出:

{"year": 2018, "type": "even number but not a leap year"}
{"year": 2019, "type": "odd number, can't be a leap year"}

使用 excludeId() 便捷方法指定排除 _id 字段:

Bson filter = Filters.empty();
Bson projection = fields(include("year", "type"), excludeId());
collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc.toJson()));

以下代码显示此投影的输出:

{"year": 2018, "type": "even number but not a leap year"}
{"year": 2019, "type": "odd number, can't be a leap year"}

使用elemMatch(String, Bson)方法变体指定一个数组投影,该投影将包含与所提供的查询筛选器匹配的数组的第一个元素。在检索到与查询筛选器(如提供)匹配的所有文档后,会发生此筛选。

注意

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

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

Bson filter = Filters.empty();
Bson projection = fields(include("year"), elemMatch("temperatures", Filters.gt("avg", 10.1)));
collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc.toJson()));

以下代码显示此投影的输出:

{"_id": {"$oid": "6042edc9f2b56342164e0790"}, "year": 2018}
{"_id": {"$oid": "6042edc9f2b56342164e0791"}, "year": 2019, "temperatures": [{"month": "March", "avg": 10.43}]}

在操作的查询部分指定匹配条件后,使用 elemMatch(String) 方法变体指定位置投影以包含数组的第一个元素。只有与查询过滤器匹配的文档才会被检索。

重要

在 MongoDB 4.4 版本中,指定的数组字段必须出现在查询筛选器中。从 MongoDB 4.4 开始,您可以对未出现在查询筛选器中的数组字段使用位置投影。

以下示例投影 temperatures 数组的第一个元素:

Bson filter = Filters.gt("temperatures.avg", 10.1);
Bson projection = fields(include("year"), elemMatch("temperatures"));
collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc.toJson()));

以下代码显示此投影的输出:

{"_id": {"$oid": "6042edc9f2b56342164e0791"}, "year": 2019, "temperatures": [{"month": "March", "avg": 10.43}]}

使用 slice() 方法投影数组片段

以下示例投影 temperatures 数组的前 6 个元素:

Bson filter = Filters.empty();
// first half of the year
Bson projection = slice("temperatures", 6);
collection.find(filter).projection(projection)
.forEach(doc -> System.out.println(doc.toJson(JsonWriterSettings.builder().indent(true).build())));

以下代码显示此投影的输出:

{
"_id": {
"$oid": "6042f1bc8ee6fa2a84d2be69"
},
"year": 2018,
"type": "even number but not a leap year",
"temperatures": [
... <January-June temperature nested documents>
]
}
{
"_id": {
"$oid": "6042f1bc8ee6fa2a84d2be6a"
},
"year": 2019,
"type": "odd number, can't be a leap year",
"temperatures": [
... <January-June temperature nested documents>
]
}

以下示例跳过 temperatures 数组的前 6 个元素,投影接下来的 6 个元素:

Bson filter = Filters.empty();
// second half of the year
Bson projection = slice("temperatures", 6, 6);
collection.find(filter).projection(projection)
.forEach(doc -> System.out.println(doc.toJson(JsonWriterSettings.builder().indent(true).build())));

以下代码显示此投影的输出:

{
"_id": {
"$oid": "6042f1bc8ee6fa2a84d2be69"
},
"year": 2018,
"type": "even number but not a leap year",
"temperatures": [
... <July-December temperature nested documents>
]
}
{
"_id": {
"$oid": "6042f1bc8ee6fa2a84d2be6a"
},
"year": 2019,
"type": "odd number, can't be a leap year",
"temperatures": [
... <July-December temperature nested documents>
]
}

使用metaTextScore()方法指定文本查询分数的投影

以下示例将文本得分投影为 score 字段的值:

Bson filter = Filters.text("even number");
Bson projection = fields(include("year"), metaTextScore("score"));
collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc.toJson()));

以下代码显示此投影的输出:

{"_id": {"$oid": "6042f1bc8ee6fa2a84d2be69"}, "year": 2018, "score": 1.25}
{"_id": {"$oid": "6042f1bc8ee6fa2a84d2be6a"}, "year": 2019, "score": 0.625}

后退

索引构建器