Search code examples
node.jsmongodbmongooseaggregation-frameworkmongodb-aggregation

Use $group with find in mongodb node.js


I want to group by user_id from order collection where there are lots of entries but I want to fetch the top 5 users that have made more orders and sum the overall price of particular user.

For example, if I made 10 orders I want to fetch my id and sum of my all orders. I have used below code but its not working:

Order.find({$group : { user_id : "$user_id"}},function(error,fetchAllTopUsers){
    console.log('##################');
      console.log(fetchAllTopUsers);
    })

I have checked this example but they are not using find with $group. I am new in Node.js and MongoDB.

Query and sum all with mongoose

Sample documents

{ user_id : '57c7f4312b3c9771219bd21c', totalprice : 100 },
{ user_id : '57c7f4312b3c9771219bd21c', totalprice : 59 },
{ user_id : '57c7f4312b3c9771219bd21c', totalprice : 26 },
{ user_id : '57c7f4312b3c9771219bd21c', totalprice : 533 },
{ user_id : '57c7f4312b3c9771219bd21c', totalprice : 544 },    
{ user_id : '57efb93fdc78c816a3a15c4a', totalprice : 250 },
{ user_id : '57efb93fdc78c816a3a15c4a', totalprice : 157 },
{ user_id : '57efb93fdc78c816a3a15c4a', totalprice : 149 },
{ user_id : '57efb93fdc78c816a3a15c4a', totalprice : 104 }

I'm expecting an output like below:

{
    user_id : '57c7f4312b3c9771219bd21c',
    finalTotal : 1262
},
{   
    user_id : '57efb93fdc78c816a3a15c4a'
    finalTotal : 660
}

Solution

  • The $group operator is only available with the aggregation framework hence you need to run an aggregation pipeline that groups the documents by the user_id field and then sorts the documents by the aggregated finalTotal field using $sort and then get the top 5 documents using $limit.

    Follow this pipeline to get the needed result:

    Order.aggregate([
        {
            "$group": {
                "_id": "$user_id",
                "finalTotal": { "$sum": "$totalprice" }
            }
        },
        { "$sort": { "finalTotal": -1 } },
        { "$limit": 5 }
    ]).exec(function(error, fetchAllTopUsers){
        console.log('##################');
        console.log(fetchAllTopUsers);
    });