skip to Main Content

I have a collection where I want to find one data based on another object data:

const data = [
{  _id :0, name:"jane",  joined : ISODate("2011-03-02"),  likes : 30, dislikes: 9},
{  _id :1, name: "joe",  joined : ISODate("2012-07-02"),  likes : 40, dislikes: 07},
{  _id : 2, name:"Ant",  joined : ISODate("2012-07-02"),  likes : 60, dislikes: 02}
]

From here I want to get the name who got most likes and I want to get the name who got maximum dislikes.

My code is like this:

const parcel = await regionModel.aggregate([
  {
    $match: {
      "likes": { $gt: 0 },
    }
  },
  {
    $group: {
      likes: {
        $max: "$likes"
      },
      dislikes: {
        $max: "$dislikes"
      }
    }
  }
])

In this code, I can get the maximum likes value and maximum likes, but how can I get the name or whole object based on the max likes and max dislikes?

Required Output:

likes: 60
MostLikedName: "Ant" ---OR--- {  _id : 2, name:"Ant",  joined : ISODate("2012-07-02"),  likes : 60, dislikes: 02}
dislikes. 09
mostDislikedName: "Jane" ---OR--- {  _id :0, name:"jane",  joined : ISODate("2011-03-02"),  likes : 30, dislikes: 9}

I tried to sort the the document but I can sort the document based on dislike or like. Also I was wondering if I can use $cond here.

2

Answers


  1. You can use sort and limit 1 to find the document with the maximum value. If you want to calculate the maximum for likes and dislikes in the same aggregation, one approach could be to use a $facet stage to get each document with the maximum.

      db.collection.aggregate([
      {
        $facet: {
          maxLikes: [
            {$sort: {likes: -1}},
            {$limit: 1}
          ],
          maxDislikes: [
            {$sort: {dislikes: -1}},
            {$limit: 1}
          ]
        }
      },
      {$unwind: "$maxDislikes"},
      {$unwind: "$maxLikes"}
    ])
    

    Mongo Playground

    Another alternative to get the maximum for likes and dislikes in a single aggregation is to use a unionWith stage, with this approach you get the two documents without transforming them:

      db.collection.aggregate([
        {$sort: {likes: -1}},
        {$limit: 1},
        {
          $unionWith: {
            coll: "collection",
            pipeline: [
              {$sort: {dislikes: -1}},
              {$limit: 1}
            ]
          }
        }
      ])
    

    Mongo playground

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search