lostintranslation
lostintranslation

Reputation: 24583

Aggregate push N number of array results

I have the following aggregate:

db.reports.aggregate({ $group: { _id: "$user", reports: { $push: {report: {properties: "$properties"} } }}}, { $project: { _id: 0, user: "$_id", reports: "$reports"} })

I would like to somehow limit the number of reports that get pushed into the array. I.E I want to limit reports to a users defined value. 1,5,10 etc. Meaning I want N number of reports (I will sort by timestamp) to be included in the reports field. Right now I am pushing all reports not sure how to limit the number of reports per user.

I tried the $limit, but that didn't work as it restricted the number of users returned not the number of reports pushed into the reports array.

Basically I want to group my reports by user, and include only a certain number of reports. I would like to limit the number of reports as early as possible such that I do not have to deal with the entire collection throughout the pipeline

Upvotes: 1

Views: 1313

Answers (1)

Amalia
Amalia

Reputation: 936

Have you looked into using group()? Let's say your data looks like this:

{ "_id" : ObjectId("732"), "user" : "john", "reports" : [  "report1",  "report2",  "report3" ] }
{ "_id" : ObjectId("733"), "user" : "john", "reports" : [  "report4",  "report5",  "report6" ] }
{ "_id" : ObjectId("734"), "user" : "max", "reports" : [  "report1",  "report2",  "report3" ] }
{ "_id" : ObjectId("735"), "user" : "max", "reports" : [  "report4" ] }
{ "_id" : ObjectId("736"), "user" : "eliza", "reports" : [  "report1",  "report2" ] }

Assuming reports is an array in the initial schema, your aggregation call becomes:

var reduce_f = function(curr, result) { 
  result.reports = result.reports.concat(curr.reports); 
}; 

var finalize_f = function(result) { 
  var limit = 5; 
  result.reports = result.reports.slice(0, limit); 
};

db.reports.group({ 
  key: { user: 1 },
  reduce: reduce_f,
  initial: { reports : [] },
  finalize: finalize_f
})

Note that group will not work in a sharded environment.

Upvotes: 2

Related Questions