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.