Docs Menu

Docs HomeDevelop ApplicationsMongoDB DriversJava Sync

Specify Which Fields to Return

On this page

  • Overview
  • Behavior
  • Explanation

In this guide, you can learn how to control which fields appear in documents returned from read operations with the MongoDB Java driver.

Many read requests require only a subset of fields in a document. For example, when logging a user in you may only need their username, and not all of their profile information. By default, queries in MongoDB return all fields in matching documents. You can use a projection to return only the data you need.

A projection is a document that instructs MongoDB which fields of a document to return. Use the Projections class to construct a projection document.

Projections work in two ways:

  • Explicitly including fields. This has the side-effect of implicitly excluding all unspecified fields.

  • Implicitly excluding fields. This has the side-effect of implicitly including all unspecified fields.

These two methods of projection are mutually exclusive: if you explicitly include fields, you cannot explicitly exclude fields, and vice versa.

Important

The _id field is not subject to these mechanics. You must explicitly exclude the _id field if you do not want it returned. You can exclude the _id field even if you have specified certain fields to include.

Consider the following collection containing documents that describe varieties of fruit:

{ "_id": 1, "name": "apples", "qty": 5, "rating": 3 },
{ "_id": 2, "name": "bananas", "qty": 7, "rating": 1 },
{ "_id": 3, "name": "oranges", "qty": 6, "rating": 2 },
{ "_id": 4, "name": "avocados", "qty": 3, "rating": 5 },

In the following query, pass the projection to return the name field of each document:

// return all documents with *only* the name field
Bson filter = Filters.empty();
Bson projection = Projections.fields(Projections.include("name"));
collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc));

The projection document specifies that the read operation result should include the name field of each returned document. As a result, this projection implicitly excludes the qty and rating fields. Chaining this projection to find() with an empty query filter yields the following results:

{ "_id": 1, "name": "apples" }
{ "_id": 2, "name": "bananas" }
{ "_id": 3, "name": "oranges" }
{ "_id": 4, "name": "avocados" }

Despite the fact that this projection only explicitly included the name field, the query returned the _id field as well.

The _id field is a special case: it is always included in every query result unless explicitly excluded. That's because the _id field is a unique identifier for each document, a property that can be useful when constructing queries.

A movies collection is a good example of why this property is useful: because remakes and even separate works sometimes reuse movie titles, you need a unique _id value to refer to any specific movie.

The _id is the only exception to the mutually exclusive include-exclude behavior in projections: you can explicitly exclude the _id field even when explicitly including other fields if you do not want _id to be present in returned documents.

// return all documents with only the name field
Bson filter = Filters.empty();
Bson projection = Projections.fields(Projections.include("name"), Projections.excludeId());
collection.find(filter).projection(projection).forEach(doc -> System.out.println(doc));

The projection document specifies that the read operation result should include the name field of each returned document, and specifies to exclude the _id field. As a result, this projection implicitly excludes the qty and rating fields. Chaining this projection to find() with an empty query filter yields the following results:

{ "name": "apples" }
{ "name": "bananas" }
{ "name": "oranges" }
{ "name": "avocados" }

You can also specify multiple fields to include in your projection.

Tip

The order in which you specify the fields in the projection does not alter the order in which they are returned.

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

This example that identifies two fields to include in the projection yields the following results:

{ "name": "apples", "rating": 3 }
{ "name": "bananas", "rating": 1 }
{ "name": "oranges", "rating": 2 }
{ "name": "avocados", "rating": 5 }

For additional projection examples, see the MongoDB Manual page on Project Fields to Return from Query.

←  Limit the Number of Returned ResultsSearch Geospatially →