[SERVER-24743] $group aggregation command should be able to set a catch-all accumulator Created: 22/Jun/16  Updated: 06/Dec/22  Resolved: 15/Mar/18

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

Type: New Feature Priority: Major - P3
Reporter: Billy Tetrud Assignee: Backlog - Query Team (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to SERVER-5781 Implement $addFields aggregation stag... Closed
Assigned Teams:
Query
Participants:

 Description   

If I'm grouping by something, unless I explicitly specify an accumulator for every field, that field will be lost. The only work around that exists right now is to re-query for the document by its _id and fill in the fields.

There should be some way to specify a $default accumulator that's performed on any unspecified field. For example:

{ $group: { _id: '$_id', number:

{ $sum: 'number'}

, $default: {"defaulted$property": {$first:$property}}} }

The above would group by _id, accumulate the number property as a sum, and for every other property it would simply add in the first value in that group for that property as the name "defaulted"+propertyName



 Comments   
Comment by Asya Kamsky [ 15/Mar/18 ]

Another way to do the same thing,

db.defaultgroup.aggregate({$group:{_id:"$i", num:{$sum:"$num"},default:{$first:"$$ROOT"}}},{$replaceRoot:{newRoot:{$mergeObjects:[ "$default","$$ROOT"]}}},{$project:{default:0}})
{ "_id" : "group2", "i" : "group2", "a" : "a", "b" : "b", "num" : 5 }
{ "_id" : "group1", "i" : "group1", "a" : "a", "b" : "b", "num" : 15 }

Comment by Asya Kamsky [ 15/Mar/18 ]

I believe you can do this already (in 3.6 anyway).

Here is an example with data and output, if this does not address the case you have in mind, let me know and provide more details about what the output should be:

db.defaultgroup.find()
{ "_id" : ObjectId("5aaac68ca7c55e2669bf44b7"), "i" : "group1", "a" : "a", "b" : "b", "num" : 5 }
{ "_id" : ObjectId("5aaac690a7c55e2669bf44b8"), "i" : "group1", "a" : "a", "b" : "b", "num" : 10 }
{ "_id" : ObjectId("5aaac697a7c55e2669bf44b9"), "i" : "group2", "a" : "a", "b" : "b", "num" : 1 }
{ "_id" : ObjectId("5aaac69ba7c55e2669bf44ba"), "i" : "group2", "a" : "a", "b" : "b", "num" : 3 }
{ "_id" : ObjectId("5aaac69fa7c55e2669bf44bb"), "i" : "group2", "a" : "a", "b" : "b", "num" : 1 }
/* grouping by "i", summing "num" and keeping first of the other fields */
db.defaultgroup.aggregate([
{$group:{
      _id:"$i", 
      num:{$sum:"$num"},
      default:{$first:"$$ROOT"}
}},
{$replaceRoot:{
     newRoot:{$mergeObjects:[ 
             "$default", 
             {_id:"$_id", num:"$num"}
     ]}
}}
])
{ "_id" : "group2", "i" : "group2", "a" : "a", "b" : "b", "num" : 5 }
{ "_id" : "group1", "i" : "group1", "a" : "a", "b" : "b", "num" : 15 }

Comment by Kelsey Schubert [ 23/Jun/16 ]

Hi fresheneesz,

Thanks for the clarification. I'm glad the workaround using $$ROOT works for you.

I'm marking this feature request to be scheduled during the next round of planning. Please continue to watch for updates.

Kind regards,
Thomas

Comment by Billy Tetrud [ 23/Jun/16 ]

Hey Thomas, it looks like 5781 is about the $project operator while this ticket is about the $group operator. I agree they're similar feature requests, but for different operators. The workaround using $$ROOT should work for this tho.

Comment by Kelsey Schubert [ 23/Jun/16 ]

Hi fresheneesz,

Thanks for opening this ticket. If I am understanding correctly, I think this feature is already tracked in SERVER-5781. Would you please review SERVER-5781, and see if the feature requested there matches your needs?

Please also be sure to inspect the work around provided in the comments to see if it fits your use case.

Kind regards,
Thomas

Generated at Thu Feb 08 04:07:17 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.