project

Specifies a list of fields which should be kept in the document.

All fields (except _id) that are not specified in this stage are unset.

_id is kept even if not specified. To exclude it, see ProjectStageOperators.excludeId.

Difference with MongoDB

In BSON, the $project stage can be used either for declaring an allow-list (by including fields, and possibly excluding the _id) or a block-list (by excluding fields). MongoDB doesn't allow a single stage usage to mix both usages.

Because this is confusing, KtMongo splits both of these use-cases into two different methods. The former (selecting fields we want to keep) is performed by this method. The latter (selecting fields we want to remove) is performed by the stage $unset.

Note that just like in MongoDB, this stage can use all operators of the $set stage.

Difference with $set

This stage and the $set stage are quite similar. In fact, both stages behave the same for fields that are specified.

However, the stages behave differently for fields that are not specified:

  • $project removes all fields that are not explicitly specified.

  • $set does not impact fields that are not explicitly specified, they are left in the exact same state as previously.

Performance

When you use a $project stage it should typically be the last stage in your pipeline, used to specify which fields to return to the client.

Using a $project stage at the beginning or middle of a pipeline to reduce the number of fields passed to subsequent pipeline stages is unlikely to improve performance, as the database performs this optimization automatically.

Example

class User(
val name: String,
val year: Int?,
)

users.aggregate()
.project {
include(User::name)
}
.toList()

In this example, the year field will not be returned by the aggregation, because it is not mentioned in the $project stage.

External resources