-
Type: New Feature
-
Resolution: Done
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: Aggregation Framework
-
Fully Compatible
-
Query 13 (04/22/16)
-
(copied to CRM)
Syntax
{ $reduce: { input: <array>, initialValue: <expression>, in: <expression> } }
Examples
> db.coll.insert([ {_id: 1, array_field: [1,2,3]} {_id: 2, array_field: []} ]); > db.coll.aggregate([{ $project: { total: { $reduce: { // Use $reduce to compute the sum. input: "$array_field", initialValue: 0, in: {$add : ["$$value", "$$this"]} } } } }]) {_id: 1, total: 6} {_id: 2, total: 0} // Example 2 > db.coll.insert([ {_id: 1, array_field: [1,2,3]} {_id: 2, array_field: []} ]); > db.coll.aggregate([{ $project: { array_totals: { $reduce: { // Compute both the sum and the product. input: "$array_field", initialValue: {sum: 0, product: 1}, in: { sum: {$add : ["$$value.sum", "$$this"]}, product: {$multiply: ["$$value.product", "$$this"]} } } } } }]) {_id: 1, array_totals: {sum: 6, product: 6}} {_id: 2, array_totals: {sum: 0, product: 1}}
Notes
- If input is an empty array, the value given to initialResult is returned.
Errors
- If a value from the input expression is anything but a single array value.
- 'input', 'initialResult', and 'in' are required options.
Old Description
We currently have the $map operator to apply an expression to each element in an array and return an array with the applied results.
Along similar lines, it would also be useful to have a $reduce operator to rollup an array into a scalar element using a specified combining function. For example, to return the sum of all array elements.
To illustrate:
Given an input of:
{ _id:1, array_field: [1,2,3] } { _id:2, array_field: [] }
We should return:
{ _id:1, array_total: 6 } { _id:2, array_total: 0 }
This is currently possible using a relatively expensive $unwind and $group (plus some additionally voodoo to handle unwinding of the empty arrays), but it would be more elegant, and likely more performant, to do something like the following:
db.coll.aggregate(
[
{ $project:
{ array_total:
{
$reduce:
{
$add: "$array_field",
}
}
}
}
]
)
[Note: the above proposed syntax is just for illustrative purposes]
- is depended on by
-
CSHARP-1662 Add $reduce expression operator for rollup of arrays
- Closed
- is related to
-
DRIVERS-297 Aggregation Framework Support for 3.4
- Closed
- related to
-
SERVER-15697 Create a string accumulator for aggregation
- Backlog
-
SERVER-14359 Allow $max, $min, $avg calculations in $project.
- Closed
-
SERVER-10682 Expose $multiply as both an accumulator and an expression
- Backlog
-
SERVER-10676 $multiply does not support a reference to an array
- Closed
-
SERVER-14872 Aggregation pipeline project expression operator to concatenate multiple arrays into one
- Closed