2

I have Post collection as like as following:

{ "_id" : ObjectId(..), "date" : ISODate("2014-03-01T08:00:00Z") }
{ "_id" : ObjectId(..), "date" : ISODate("2014-03-01T09:00:00Z") }
{ "_id" : ObjectId(..), "date" : ISODate("2014-03-15T09:00:00Z") }
{ "_id" : ObjectId(..), "date" : ISODate("2014-04-04T11:21:39.736Z") }
{ "_id" : ObjectId(..), "date" : ISODate("2014-04-04T21:23:13.331Z") }

I need to get total count and max date of post. So desired result for coeumtns above is the following:

{count: 5, date: ISODate("2014-04-04T21:23:13.331Z")}

How to get desired result with single query to MongoDB without handling and counting in application code?

EDIT: @chridam thanks for the response. I've accepted your answer as best one! Could help me with one more thing?

Let's say that posts are not exists yet, so I need to fetch result with zero count and current date as timestamp like the following:

{count: 0, [Date.now()]}

Is it possible with MongoDB ?

Erik
  • 14,060
  • 49
  • 132
  • 218

1 Answers1

3

Use the $max and $sum operators as

Model.aggregate([ 
    {
        "$group": {
            "_id": null,
            "count": { "$sum": 1 },
            "date": { "$max": "$date" }
        }
    }
]).exec(function (err, result) {
   console.log(result);
})

EDIT: Addressing your further question with regards to an empty collection, the aggregate function will return an empty cursor since there wont be any documents to aggregate in the collection. So you would need to address this logic on the client i.e. check the results from the above aggregation, if the result is an empty array then create the placeholder doc as required:

Model.aggregate([ 
    {
        "$group": {
            "_id": null,
            "count": { "$sum": 1 },
            "date": { "$max": "$date" }
        }
    }
]).exec(function (err, result) {
     console.log(result);
     if (!result.length) {
         result = [{ count:0, date: new Date() }];   
     }
});
chridam
  • 100,957
  • 23
  • 236
  • 235
  • @Erik I've addressed your further question but just so you know for future references, the general case here on SO is if you need to address further question it's best to create a new question, not edit the original one especially when an answer to the original question has been accepted. Read more on http://meta.stackexchange.com/questions/43478/ – chridam May 29 '16 at 18:01
  • @Erik No worries, always happy to help :) – chridam May 29 '16 at 21:07
  • just note: even you do `_id: null` I get that field in result in response. How can I completly exclude `_id` from result? – Erik May 30 '16 at 07:50
  • @Erik Follow answers from this question [How to hide _id from Aggregation?](http://stackoverflow.com/questions/15776453/how-to-hide-id-from-aggregation) – chridam May 30 '16 at 11:00