Docs Menu

Docs HomeDevelop ApplicationsMongoDB DriversJava Sync

Projections Builders

On this page

  • Overview
  • Sample Documents and Examples
  • Projection Operations
  • Inclusion
  • Exclusion
  • Combining Projections
  • Exclusion of _id
  • Project an Array Element Match
  • Project an Array Slice
  • Project a Text Score

In this guide, you can learn how to specify projections using builders in the MongoDB Java driver.

MongoDB supports field projection, specifying which fields to include and exclude when returning results from a query. Projection in MongoDB follows some basic rules:

  • The _id field is always included unless explicitly excluded

  • Specifying a field for inclusion implicitly excludes all other fields except the _id field

  • Specifying a field for exclusion removes only that field in a query result

Find more information about projection mechanics here.

The Projections class provides static factory methods for all the MongoDB projection operators. Each method returns an instance of the BSON type which you can pass to any method that expects a projection.

Tip

For brevity, you may choose to import the methods of the Projections class statically:

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

The following examples assume this static import.

The following sections feature examples that run query and projection operations on a sample collection called projection_builders. Each section uses a variable named collection to refer to the MongoCollection instance of the projection_builders collection.

The collection contains the following documents, representing the monthly average temperatures in Celsius for the years 2018 and 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 }
]
}

The following sections contain information on the available projection operations and how to construct them using the Projections class.

Use the include() method to specify the inclusion of one or more fields.

The following example includes the year field and (implicitly) the _id field:

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

The following code shows the output from this projection:

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

The following example includes the year and type fields and (implicitly) the _id field:

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

The following code shows the output from this projection:

{"_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"}

Use the exclude() method to specify the exclusion of one or more fields.

The following example excludes the temperatures field:

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

The following code shows the output from this projection:

{"_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"}

The following example excludes the type and temperatures fields:

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

The following code shows the output from this projection:

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

Use the fields() method to combine multiple projections.

The following example includes the year and type fields and excludes the _id field:

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

The following code shows the output from this projection:

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

Use the excludeId() convenience method to specify the exclusion of the _id field:

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

The following code shows the output from this projection:

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

Use the elemMatch(String, Bson) method variant to specify an array projection that will include the first element of an array that matches a supplied query filter. This filtering occurs after all documents matching the query filter (if supplied) are retrieved.

Note

Only the first element that matches the specified query filter will be included, regardless of how many matches there may be.

The following example projects the first element of the temperatures array where the avg field is greater that 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()));

The following code shows the output from this projection:

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

When you've specified matching criteria in the query portion of your operation, use the elemMatch(String) method variant to specify a positional projection to include the first element of an array. Only documents that match the query filter will be retrieved.

Important

In MongoDB versions < 4.4, the specified array field must appear in the query filter. Beginning in MongoDB 4.4, you can use a positional project on an array field that does not appear in the query filter.

The following example projects the first element of the temperatures array:

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()));

The following code shows the output from this projection:

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

Use the slice() method to project a slice of an array.

The following example projects the first 6 elements of the temperatures array:

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())));

The following code shows the output from this projection:

{
"_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>
]
}

The following example skips the first 6 elements of the temperatures array and projects the next 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())));

The following code shows the output from this projection:

{
"_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>
]
}

Use the metaTextScore() method to specify a projection of the score of a text query

The following example projects the text score as the value of the score field:

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()));

The following code shows the output from this projection:

{"_id": {"$oid": "6042f1bc8ee6fa2a84d2be69"}, "year": 2018, "score": 1.25}
{"_id": {"$oid": "6042f1bc8ee6fa2a84d2be6a"}, "year": 2019, "score": 0.625}
←  Indexes BuildersSorts Builders →