对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

投影构建器

在本指南中,您可以学习;了解如何使用Java Reactive Streams驾驶员中的构建者指定投影。

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");
FindPublisher<Document> findPublisher = collection.find(filter).projection(projection);
Flux.from(findPublisher)
.doOnNext(doc -> System.out.println(doc.toJson()))
.blockLast();
{"_id": {"$oid": "6042edc9f2b56342164e0790"}, "year": 2018}
{"_id": {"$oid": "6042edc9f2b56342164e0791"}, "year": 2019}

以下示例包括 yeartype 和隐式 _id 字段:

Bson filter = Filters.empty();
Bson projection = include("year", "type");
FindPublisher<Document> findPublisher = collection.find(filter).projection(projection);
Flux.from(findPublisher)
.doOnNext(doc -> System.out.println(doc.toJson()))
.blockLast();
{"_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");
FindPublisher<Document> findPublisher = collection.find(filter).projection(projection);
Flux.from(findPublisher)
.doOnNext(doc -> System.out.println(doc.toJson()))
.blockLast();
{"_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");
FindPublisher<Document> findPublisher = collection.find(filter).projection(projection);
Flux.from(findPublisher)
.doOnNext(doc -> System.out.println(doc.toJson()))
.blockLast();
{"_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"));
FindPublisher<Document> findPublisher = collection.find(filter).projection(projection);
Flux.from(findPublisher)
.doOnNext(doc -> System.out.println(doc.toJson()))
.blockLast();
{"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());
FindPublisher<Document> findPublisher = collection.find(filter).projection(projection);
Flux.from(findPublisher)
.doOnNext(doc -> System.out.println(doc.toJson()))
.blockLast();
{"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)));
FindPublisher<Document> findPublisher = collection.find(filter).projection(projection);
Flux.from(findPublisher)
.doOnNext(doc -> System.out.println(doc.toJson()))
.blockLast();
{"_id": {"$oid": "6042edc9f2b56342164e0790"}, "year": 2018}
{"_id": {"$oid": "6042edc9f2b56342164e0791"}, "year": 2019, "temperatures": [{"month": "March", "avg": 10.43}]}

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

重要

在 4.4 之前的MongoDB版本中,指定的大量字段必须出现在查询过滤中。从MongoDB 4.4 开始,您可以对未出现在查询过滤中的大量字段使用位置项目。

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

Bson filter = Filters.gt("temperatures.avg", 10.1);
Bson projection = fields(include("year"), elemMatch("temperatures"));
FindPublisher<Document> findPublisher = collection.find(filter).projection(projection);
Flux.from(findPublisher)
.doOnNext(doc -> System.out.println(doc.toJson()))
.blockLast();
{"_id": {"$oid": "6042edc9f2b56342164e0791"}, "year": 2019, "temperatures": [{"month": "March", "avg": 10.43}]}

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

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

Bson filter = Filters.empty();
Bson projection = slice("temperatures", 6);
FindPublisher<Document> findPublisher = collection.find(filter).projection(projection);
Flux.from(findPublisher)
.doOnNext(doc -> System.out.println(doc.toJson(JsonWriterSettings.builder().indent(true).build())))
.blockLast();
{
"_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();
Bson projection = slice("temperatures", 6, 6);
FindPublisher<Document> findPublisher = collection.find(filter).projection(projection);
Flux.from(findPublisher)
.doOnNext(doc -> System.out.println(doc.toJson(JsonWriterSettings.builder().indent(true).build())))
.blockLast();
{
"_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"));
FindPublisher<Document> findPublisher = collection.find(filter).projection(projection);
Flux.from(findPublisher)
.doOnNext(doc -> System.out.println(doc.toJson()))
.blockLast();
{"_id": {"$oid": "6042f1bc8ee6fa2a84d2be69"}, "year": 2018, "score": 1.25}
{"_id": {"$oid": "6042f1bc8ee6fa2a84d2be6a"}, "year": 2019, "score": 0.625}