MongoDB: aggregation, $group by multiple (two) fields, with sorting (receiving latest) results
I want to receiving the following data
item: 168652 groupedBy: { 1602 and 7 }, { 1603 and 5 }
- You need to group at item at the last
- Initially you need to group at realm, then you need to get latest timestamp i.e max
db.collection.aggregate([ { $group: { _id: { connected_realm_id: "$connected_realm_id" }, "data": { "$max": "$last_modified" }, "item": { "$first": "$item.id" } } }, { $project: { "connected_realm_id": "$_id.connected_realm_id", "last_modified": "$data", "item": 1, "_id": 0 } }, { "$group": { "_id": "$item", "groupedBy": { "$push": "$$ROOT" } } }])
EDIT:
db.collection.aggregate([ { $group: { _id: { connected_realm_id: "$connected_realm_id", latest_timestamp: { $max: "$last_modified" }, }, data: { $push: "$$ROOT" } } }, { "$unwind": "$data" }, { $group: { _id: { connected_realm_id: "$data.connected_realm_id" }, "data": { "$max": "$data.last_modified" }, "item": { "$first": "$data.item.id" } } }, { $project: { "connected_realm_id": "$_id.connected_realm_id", "last_modified": "$data", "item": 1, "_id": 0 } }, { "$group": { "_id": "$item", "groupedBy": { "$push": "$$ROOT" } } }])
Update:
As OP derived from above edit, this solves OP's problem
db.collection.aggregate([ { $group: { _id: { connected_realm_id: "$connected_realm_id", latest_timestamp: { $max: "$last_modified" }, }, data: { $push: "$$ROOT" } } }, { "$unwind": "$data" }, { $group: { _id: { connected_realm_id: "$data.connected_realm_id" }, "data": { "$max": "$data.last_modified" }, "item": { "$push": "$data" } } }])
The correct (final solution) at MongoPlayground
Dataset:
[ { item: { id: 168652 }, connected_realm_id: 1602, last_modified: 1596719280 }, { item: { id: 168652 }, connected_realm_id: 1602, last_modified: 1596719280 }, { item: { id: 168652 }, connected_realm_id: 1602, last_modified: 1596719280 }, { item: { id: 168652 }, connected_realm_id: 1602, last_modified: 1596719280 }, { item: { id: 168652 }, connected_realm_id: 1602, last_modified: 2 }, { item: { id: 168652 }, connected_realm_id: 1602, last_modified: 3 }, { item: { id: 168652 }, connected_realm_id: 1602, last_modified: 4 }, { item: { id: 168652 }, connected_realm_id: 1602, last_modified: 5 }, { item: { id: 168652 }, connected_realm_id: 1602, last_modified: 1596719280 }, { item: { id: 168652 }, connected_realm_id: 1602, last_modified: 1596719280 }, { item: { id: 168652 }, connected_realm_id: 1603, last_modified: 1596719267 }, { item: { id: 168652 }, connected_realm_id: 1603, last_modified: 1596719267 }, { item: { id: 168652 }, connected_realm_id: 1603, last_modified: 1596719267 }, { item: { id: 168652 }, connected_realm_id: 1603, last_modified: 1596719267 }, { item: { id: 168652 }, connected_realm_id: 1603, last_modified: 1 }, { item: { id: 168652 }, connected_realm_id: 1603, last_modified: 2 }, { item: { id: 168652 }, connected_realm_id: 1603, last_modified: 3 }, { item: { id: 168652 }, connected_realm_id: 1603, last_modified: 4 }, { item: { id: 168652 }, connected_realm_id: 1603, last_modified: 5 }, { item: { id: 168652 }, connected_realm_id: 1603, last_modified: 1596719267 }]
Aggregation Query
db.collection.aggregate([ { $group: { _id: { connected_realm_id: "$connected_realm_id" }, latest: { $max: "$last_modified" }, data: { $push: "$$ROOT" } } }, { $unwind: "$data" }, { $addFields: { "data.latest": { $cond: { if: { $eq: [ "$data.last_modified", "$latest" ] }, then: "$latest", else: "$false" } } } }, { "$replaceRoot": { "newRoot": "$data" } }, { "$match": { "latest": { "$exists": true, "$ne": null } } }])