[CSHARP-1662] Add $reduce expression operator for rollup of arrays Created: 10/May/16  Updated: 27/May/22  Resolved: 31/Aug/16

Status: Closed
Project: C# Driver
Component/s: Linq
Affects Version/s: None
Fix Version/s: 2.4

Type: New Feature Priority: Major - P3
Reporter: Rathi Gnanasekaran Assignee: Craig Wilson
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
depends on SERVER-17258 Add $reduce expression operator for r... Closed
Epic Link: MongoDB 3.4
Server Compat: 3.3

 Description   

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]



 Comments   
Comment by Githook User [ 29/Sep/16 ]

Author:

{u'username': u'craiggwilson', u'name': u'Craig Wilson', u'email': u'craiggwilson@gmail.com'}

Message: CSHARP-1662: added support for $reduce. Also included a new ImmutableTypeClassMapConvention which was needed to support anonymous types in LINQ's Aggregate method.
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/9aa35d8a54650c55977f3abcc728773b7cda38d8

Comment by Githook User [ 24/Sep/16 ]

Author:

{u'username': u'craiggwilson', u'name': u'Craig Wilson', u'email': u'craiggwilson@gmail.com'}

Message: CSHARP-1662: added support for $reduce. Also included a new ImmutableTypeClassMapConvention which was needed to support anonymous types in LINQ's Aggregate method.
Branch: v2.4.x
https://github.com/mongodb/mongo-csharp-driver/commit/9aa35d8a54650c55977f3abcc728773b7cda38d8

Comment by Githook User [ 21/Sep/16 ]

Author:

{u'username': u'craiggwilson', u'name': u'Craig Wilson', u'email': u'craiggwilson@gmail.com'}

Message: CSHARP-1662: added support for $reduce. Also included a new ImmutableTypeClassMapConvention which was needed to support anonymous types in LINQ's Aggregate method.
Branch: v2.4.x
https://github.com/mongodb/mongo-csharp-driver/commit/93e3c35ed373ec9c084e95fad18a8878c71bf5e1

Comment by Githook User [ 16/Sep/16 ]

Author:

{u'username': u'craiggwilson', u'name': u'Craig Wilson', u'email': u'craiggwilson@gmail.com'}

Message: CSHARP-1662: added support for $reduce. Also included a new ImmutableTypeClassMapConvention which was needed to support anonymous types in LINQ's Aggregate method.
Branch: v2.4.x
https://github.com/mongodb/mongo-csharp-driver/commit/77f97453a7b4c5caceff2694186836770e93c9ca

Comment by Githook User [ 31/Aug/16 ]

Author:

{u'username': u'craiggwilson', u'name': u'Craig Wilson', u'email': u'craiggwilson@gmail.com'}

Message: CSHARP-1662: added support for $reduce. Also included a new ImmutableTypeClassMapConvention which was needed to support anonymous types in LINQ's Aggregate method.
Branch: v2.4.x
https://github.com/mongodb/mongo-csharp-driver/commit/bfe3c50fea4c8bff1d738ca65de7c12ce8768545

Comment by Githook User [ 31/Aug/16 ]

Author:

{u'username': u'craiggwilson', u'name': u'Craig Wilson', u'email': u'craiggwilson@gmail.com'}

Message: CSHARP-1662: added support for $reduce. Also included a new ImmutableTypeClassMapConvention which was needed to support anonymous types in LINQ's Aggregate method.
Branch: v2.4.x
https://github.com/mongodb/mongo-csharp-driver/commit/5c151ba67af1040ab82f4038af04bbe2a578ca7d

Generated at Wed Feb 07 21:40:18 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.