group
Combines many documents into few documents.
The resulting documents contain fields generated by accumulating all input documents. To learn more about accumulation operators, see AccumulationOperators.
$group can be used in two different ways:
Without specifying a key: this stage behaves like Kotlin's
fold()function, returning a single document that accumulates the data from all results.With a key: this stage behaves like Kotlin's
groupBy()function, returning multiple documents which each acculumate the data of their matching results.
Example with a single result
If we have users with an account balance, we can find out the total account balance of all users.
class User(
val name: String,
val balance: Int,
)
class Result(
val totalBalance: Int,
)
users.aggregate()
.group {
Result::totalBalance sum User::balance
}This is similar to the following Kotlin code:
users.toList()
.fold(0) { acc, it -> acc + it.balance }Or even just:
users.toList()
.sumOf { it.balance }To see the list of available accumulation operators, see AccumulationOperators.
Example with multiple results
If we have users with an account balance across different cities, we may be interested in the average balance of users in each city.
class User(
val name: String,
val balance: Int,
val city: String,
)
class Result(
val _id: String,
val averageBalance: Double,
)
users.aggregate()
.group {
// Group by city name
Result::_id set User::city
// Each each group, compute the average balance
Result::averageBalance average User::balance
}This is similar to the following Kotlin code:
users.toList()
.groupBy { it.city }
.mapValues { (_, users) -> users.map { it.balance }.average() }To learn more about creating multiple groups, see GroupStageOperators.set.
To see the list of available accumulation operators, see AccumulationOperators.
Performance
$group is a blocking stage, which causes the pipeline to wait for all input data to be retrieved for the blocking stage before processing the data. A blocking stage may reduce performance because it reduces parallel processing for a pipeline with multiple stages. A blocking stage may also use substantial amounts of memory for large data sets.