Search code examples
node.jsmongodbmongodb-querymongoose-schema

I want latest logs from userlogs collection based on userId with group by concept using MongoDB NodeJS


I want latest logs from userlogs collection based on userId with group by concept For example, if I having 10 logs record with two different users, and want to fetch logs details.

My code:

let options = [
  {
    "$sort": {
      "updatedAt": -1
    }
  },
  {
    "$group": {
      "_id": "$userId"
    }
  },
  {
    "$group": {
      "_id": null,
      "count": {
        "$sum": 1
      },
      "results": {
        "$push": "$$ROOT"
      }
    }
  },
  {
    "$project": {
      "count": 1,
      "results": {
        "$slice": [
          "$results",
          0,
          10
        ]
      }
    }
  }
];
Note.aggregate(options).allowDiskUse(true).exec((err, result) => {
    console.log(result)
});

Sample documents in my logs collection:

{ userId : '57c7f4312b3c9771219bd21c', logs : "sample entry", "updatedAt": "2020-08-05T11:31:39.694Z" },
{ userId : '57c7f4312b3c9771219bd21c', logs : "sample entry", "updatedAt": "2020-08-04T11:31:39.694Z" },
{ userId : '57c7f4312b3c9771219bd21c', logs : "sample entry", "updatedAt": "2020-08-03T11:31:39.694Z" },
{ userId : '57c7f4312b3c9771219bd21c', logs : "sample entry", "updatedAt": "2020-08-02T11:31:39.694Z" },
{ userId : '57c7f4312b3c9771219bd21c', logs : "sample entry", "updatedAt": "2020-08-01T11:31:39.694Z" },
{ userId : '57efb93fdc78c816a3a15c4a', logs : "sample entry", "updatedAt": "2020-08-05T11:31:39.694Z" },
{ userId : '57efb93fdc78c816a3a15c4a', logs : "sample entry", "updatedAt": "2020-08-03T11:31:39.694Z" },
{ userId : '57efb93fdc78c816a3a15c4a', logs : "sample entry", "updatedAt": "2020-08-02T11:31:39.694Z" },
{ userId : '57efb93fdc78c816a3a15c4a', logs : "sample entry", "updatedAt": "2020-08-01T11:31:39.694Z" }

I'm expecting an output like below:

[
    { userId : '57c7f4312b3c9771219bd21c', logs : "sample entry", "updatedAt": "2020-08-05T11:31:39.694Z" },
    { userId : '57efb93fdc78c816a3a15c4a', logs : "sample entry", "updatedAt": "2020-08-05T11:31:39.694Z" }
]

Thanks in advance


Solution

    • $sort by updatedAt in descending order
    • $group by userId and make array of logs
    • $slice to get latest first record
    let options = [
      { $sort: { updatedAt: -1 } },
      {
        $group: {
          _id: "$userId",
          latest: { $push: "$$ROOT" }
        }
      },
      { $project: { latest: { $slice: ["$latest", 1] } } }
    ];
    

    Playground