Reputation: 2942
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
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