title: MongoDB group by ID and then by date
body: <p>I have a collection in my MongoDB database that stores durations for people who are in groups, it looks a like this:</p>
  
  <pre><code>[{
      "_id": "5c378eecd11e570240a9b0ac",
      "state": "DRAFT",
      "groupId": "5c378eebd11e570240a9ae49",
      "personId": "5c378eebd11e570240a9aee1",
      "date": "2019-01-07T00:00:00.000Z",
      "duration": 480,
      "__v": 0
  },
  {
      "_id": "5c378eecd11e570240a9b0bb",
      "state": "DRAFT",
      "groupId": "5c378eebd11e570240a9ae58",
      "personId": "5c378eebd11e570240a9aeac",
      "date": "2019-01-07T00:00:00.000Z",
      "duration": 480,
      "__v": 0
  },
  {
      "_id": "5c378eecd11e570240a9b0c5",
      "state": "DRAFT",
      "groupId": "5c378eebd11e570240a9ae3e",
      "personId": "5c378eebd11e570240a9aef6",
      "date": "2019-01-07T00:00:00.000Z",
      "duration": 480,
      "__v": 0
  }]
  </code></pre>
  
  <p>I would like to be able to run an aggregate query which returns a collection of <code>personIds</code> and the <code>duration</code> grouped per day with the corresponding <code>groupId</code>, which would look like this:</p>
  
  <pre><code>[{
      "personId": "5c378eebd11e570240a9aee1",
      "time": [{
          "date": "2019-01-07T00:00:00.000Z",
          "entries": [{
              "groupId": "5c378eebd11e570240a9ae49",
              "duration": 480,
              "state": "DRAFT"
          }]
      }]
  }, {
      "personId": "5c378eebd11e570240a9aeac",
      "time": [{
          "date": "2019-01-07T00:00:00.000Z",
          "entries": [{
              "groupId": "5c378eebd11e570240a9ae58",
              "duration": 480,
              "state": "DRAFT"
          }]
      }]
  }, {
      "personId": "5c378eebd11e570240a9aef6",
      "time": [{
          "date": "2019-01-07T00:00:00.000Z",
          "entries": [{
              "groupId": "5c378eebd11e570240a9ae3e",
              "duration": 480,
              "state": "DRAFT"
          }]
      }]
  }]
  </code></pre>
  
  <p>So far, I have written the following aggregation (I'm using Mongoose, hence the syntax):</p>
  
  <pre><code>Time.aggregate()
      .match({ date: { $gte: new Date(start), $lte: new Date(end) } })
      .group({
        _id: '$personId',
        time: { $push: { date: '$date', duration: '$duration', state: '$state' } },
      })
      .project({ _id: false, personId: '$_id', time: '$time' })
  </code></pre>
  
  <p>Which returns the following:</p>
  
  <pre><code>[{
      "personId": "5c378eebd11e570240a9aed1",
      "time": [{
          "date": "2019-01-11T00:00:00.000Z",
          "duration": 480,
          "state": "DRAFT"
      }, {
          "date": "2019-01-11T00:00:00.000Z",
          "duration": 480,
          "state": "DRAFT"
      }
      // ...
  }]
  </code></pre>
  
  <p>Hopefully you can see that the <code>duration</code>s are being grouped by <code>personId</code> but I've not been able to figure out how to apply another grouping to the <code>time</code> array as the <code>date</code>s are duplicated if a <code>personId</code> has more than one <code>duration</code> for a given date.</p>
  
  <p>Is it possible to group by and ID, push to an array and then group the values in that array as an aggregation or will my application need to map/reduce the results instead?</p>