alex.mironov
alex.mironov

Reputation: 2942

Map aggregation results in Mongo

Here is the data set:

{ "_id" : "1", "key" : "111", "payload" : 100, "type" : "foo", "createdAt" : ISODate("2016-07-08T11:59:18.000Z") }
{ "_id" : "2", "key" : "111", "payload" : 100, "type" : "bar", "createdAt" : ISODate("2016-07-09T11:59:19.000Z") }
{ "_id" : "3", "key" : "222", "payload" : 100, "type" : "foo", "createdAt" : ISODate("2016-07-10T11:59:20.000Z") }
{ "_id" : "4", "key" : "222", "payload" : 100, "type" : "foo", "createdAt" : ISODate("2016-07-11T11:59:21.000Z") }
{ "_id" : "5", "key" : "222", "payload" : 100, "type" : "bar", "createdAt" : ISODate("2016-07-12T11:59:22.000Z") }

I have to group them by key:

db.items.aggregate([{$group: {_id: {key: '$key'}}}])

that produces the next set:

{ "_id" : { "key" : "111" } }
{ "_id" : { "key" : "222" } }

And after that I have to retrieve the most recent values of foo and bar per each group record. My question is what is the most optimal way to do it? I can iterate the items in javascript and perform additional roundtrip to DB per each group result. But I'm not sure if it's time-efficient.

Upvotes: 0

Views: 647

Answers (1)

Mr Tarsa
Mr Tarsa

Reputation: 6652

I am not sure about the most optimal way to do it, but the easy one will be to expand your aggregation pipeline like

db.items.aggregate([
  {
    $group: 
      {
        _id: { key: "$key", type: "$type" }, 
        last: { $max: "$createdAt" } 
      }
  }, 
  { 
    $group: 
    { 
      _id: { key: "$_id.key" }, 
      mostRecent: { $push: { type: "$_id.type", createdAt: "$last" } } 
    } 
  } 
]);

that for your collection of documents will result into

{ "_id" : { "key" : "222" }, "mostRecent" : [ { "type" : "bar", "createdAt" : ISODate("2016-07-12T11:59:22Z") }, { "type" : "foo", "createdAt" : ISODate("2016-07-11T11:59:21Z") } ] }
{ "_id" : { "key" : "111" }, "mostRecent" : [ { "type" : "bar", "createdAt" : ISODate("2016-07-09T11:59:19Z") }, { "type" : "foo", "createdAt" : ISODate("2016-07-08T11:59:18Z") } ] }

Upvotes: 2

Related Questions