[SERVER-10682] Expose $multiply as both an accumulator and an expression Created: 04/Sep/13  Updated: 06/Dec/22

Status: Backlog
Project: Core Server
Component/s: Aggregation Framework
Affects Version/s: 2.5.2
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Jeremy Mikola Assignee: Backlog - Query Execution
Resolution: Unresolved Votes: 0
Labels: accumulator, expression
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
Duplicate
is duplicated by SERVER-32789 Add $product to calculate aggregate m... Closed
is duplicated by SERVER-10676 $multiply does not support a referenc... Closed
Related
related to SERVER-10681 $multiply operator cannot processed a... Closed
is related to SERVER-17258 Add $reduce expression operator for r... Closed
is related to SERVER-10676 $multiply does not support a referenc... Closed
Assigned Teams:
Query Execution
Participants:

 Description   

This would perform like $sum, but compute the multiplied product instead of an additive sum.

Just as these operators became available both as accumulators (for grouping) and expressions (for simple transformations like in $project) in 3.2, we should make $multiply work with an array of inputs, and also be available as an accumulator during the $group stage.



 Comments   
Comment by Charlie Swanson [ 19/Jan/18 ]

There have been several similar requests for something like this feature, so I've updated the summary and description to reflect our plans for what we would likely implement, which I think would address all the issues linked as duplicates here.

Comment by Asya Kamsky [ 15/Apr/16 ]

Implementation of $reduce expression (SERVER-17258) should make it possible to multiply elements in an array during $project.

Comment by Jeremy Mikola [ 04/Sep/13 ]

As we discussed in the kitchen, deprecating $add and sticking with the arithmetic operator names makes sense.

As for a test case, I think something based on what I wrote in SERVER-10681 would work:

> db.foo.find()
{ "_id" : ObjectId("522784a423582cd7f71acca7"), "x" : 2 }
{ "_id" : ObjectId("522784a523582cd7f71acca8"), "x" : 3 }
{ "_id" : ObjectId("522784a623582cd7f71acca9"), "x" : 4 }
> pipeline
[
    {
        "$group" : {
            "_id" : 1,
            "product" : {
                "$multiply" : "$x"
            }
        }
    }
]
> db.foo.aggregate(pipeline)
{
	"result" : [
		{
			"_id" : 1,
			"x" : 24
		}
	],
	"ok" : 1
}

Comment by Scott Hernandez (Inactive) [ 04/Sep/13 ]

I'm suggesting we should really use $sum in both places and deprecate $add. $multiply can work in both contexts, and with arrays – no need for a sep. pipeline stage.

Do you have test case for what you are interested in supporting with input and result?

Comment by Jeremy Mikola [ 04/Sep/13 ]

Even if SERVER-10676 was implemented, this would require a group step to collect values in an array, and then a projection to multiply them.

Supporting $multiply as a first-class $group operator doesn't seem correct, for the same reason that we distinguish $sum from $add. Certainly, if you wanted to compute the combined products of arrays of numbers across documents you're grouping, I suppose you could do:

{ $product: { $multiply: "$vals" }}

Comment by Scott Hernandez (Inactive) [ 04/Sep/13 ]

Why not just make $multiple work with arrays, and in $group?

Generated at Thu Feb 08 03:23:47 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.