title: Mongodb: how to group by key and save additional information for items in group
body: <p>I have messages system in mongodb. Messages object looks like this:</p>
  <pre><code>{
      who: String,
      whom: String,
      when: Date
  }
  </code></pre>
  <p>So, for example, when user <strong>1</strong> sends message to user <strong>2</strong> I have:</p>
  <pre><code>{ who: &quot;1&quot;, whom: &quot;2&quot;, when: MSG_DATE }
  </code></pre>
  <p>And when user <strong>2</strong> sends message to <strong>1</strong> in response the following row is added:</p>
  <pre><code>{ who: &quot;2&quot;, whom: &quot;1&quot;, when: MSG_DATE }
  </code></pre>
  <p>Now I need to collect unique dialogs in UI for user <strong>1</strong>, for example.</p>
  <pre><code>[
      {
          &quot;$match&quot;: {
              &quot;$or&quot;: [
                  { &quot;who&quot;: &quot;1&quot; },
                  { &quot;whom&quot;: &quot;1&quot; }
              ]
          }
      },
      {
          &quot;$group&quot;: {
              &quot;_id&quot;: &quot;a&quot;,
              &quot;dialogs_who&quot;: { &quot;$addToSet&quot;: &quot;$who&quot; },
              &quot;dialogs_whom&quot;: { &quot;$addToSet&quot;: &quot;$whom&quot; }
          }
      },
      {
          &quot;$project&quot;: {
              &quot;name&quot;: &quot;$_id&quot;,
              &quot;profiles&quot;: {
                  &quot;$setUnion&quot;: [ &quot;$dialogs_who&quot;, &quot;$dialogs_whom&quot; ]
              }
          }
      }
  ]
  </code></pre>
  <p>This will return me : <code>[&quot;1&quot;, &quot;2&quot;]</code>. In code I just skip dialog <code>1</code> for user <strong>1</strong>.</p>
  <p>With this aggregation I search for messages where <code>who</code> or <code>whom</code> is user we are loading info for (<strong>1</strong>). Results are added to set to make it unique and finally two sets are merged into one. It works, bu I need to store latest date message for each dialog.</p>
  <p>So if there are such rows in db:</p>
  <pre><code>{ who: &quot;1&quot;, whom: &quot;2&quot;, when: MSG_DATE1 },
  { who: &quot;2&quot;, whom: &quot;1&quot;, when: MSG_DATE2 },
  { who: &quot;3&quot;, whom: &quot;1&quot;, when: MSG_DATE3 },
  { who: &quot;3&quot;, whom: &quot;4&quot;, when: MSG_DATE4 }    // It's not dialog with 1
  </code></pre>
  <p>Here we have two unique dialogs (minus dialog with <strong>1</strong>) for user <strong>1</strong>: [&quot;1&quot;, &quot;2&quot;, &quot;3&quot;]. How to add into aggregation storing of latest <code>when</code> date for dialog with.</p>
  <p>So if <strong>MSG_DATE2</strong> &gt; <strong>MSG_DATE_1</strong> I want result like:</p>
  <pre><code>[
      &quot;2&quot;: MSG_DATE2,
      &quot;3&quot;: MSG_DATE4
  }
  </code></pre>