user2500558
user2500558

Reputation: 73

Tricky Mongoose Aggregation Query

The following schema is given:

LogSchema {
    ...
    likes: Number,
    author: User,
    created_at: Date
    ...
}

The following query seems to be very tricky:

Get the top X users who have the most likes for all today created logs.

The result should look like this:

I have no clue how I can attack that. I know, that I could use some Aggregation, but how should it be done here, since likes are bound to users somehow.

Upvotes: 0

Views: 123

Answers (1)

zangw
zangw

Reputation: 48356

Here is one example with commands .aggregate() used under Mongo Shell with test data

{ "_id" : ObjectId("56c912a1ebf94ca549e4ab8f"), "likes" : 123, "author" : "x", "created_at" : ISODate("2016-02-21T01:28:01.549Z") }
{ "_id" : ObjectId("56c912aaebf94ca549e4ab90"), "likes" : 120, "author" : "x", "created_at" : ISODate("2016-02-21T01:28:10.116Z") }
{ "_id" : ObjectId("56c912b4ebf94ca549e4ab91"), "likes" : 12, "author" : "y", "created_at" : ISODate("2016-02-21T01:28:20.996Z") }
{ "_id" : ObjectId("56c912bbebf94ca549e4ab92"), "likes" : 22, "author" : "y", "created_at" : ISODate("2016-02-21T01:28:27.644Z") }

Commands

> var d = new Date();
> d.setHours(0, 0, 0); // set to the first second of today, used for query today logs
> db.log.aggregate([
     // query today logs by `create_at`
     {$match: {created_at: {$gt: d}}}, 
     // group by author and sum the `likes`
     {$group: {_id: '$author', likes: {$sum: '$likes'}}}
  ]).map(function(val) {
     // map the field per request
     return {[val._id]: val.likes}
  });

Result

[ { "y" : 34 }, { "x" : 243 } ]

With mongoose aggregate, please try it

var p = Log.aggregate([
           // query today logs by `create_at`
           {$match: {created_at: {$gt: d}}}, 
           // group by author and sum the `likes`
           {$group: {_id: '$author', likes: {$sum: '$likes'}}}
        ]).exec();
p.then(function(vals){
        return vals.map(function(val) {
           return {[val._id]: val.likes};
        });
});

Upvotes: 2

Related Questions