2

Hi I want to build a leader board that will rank users based on the likes they have accumulated in all their posts.

My database for Posts

  user: {
    type: Schema.Types.ObjectId,
  },
  text: {
    type: String,
    required: true,
  },
  imageURL: {
    type: [String],
  },
  name: {
    type: String,
    required: true,
  },
  category: {
    type: String,
  },
  likes: [
    {
      user: {
        type: Schema.Types.ObjectId,
      },
    },
  ],
  date: {
    type: Date,
    default: Date.now,
  }

My database for user:


  name: {
    type: String,
    required: true,
  },
  email: {
    type: String,
    required: true,
    unique: true,
  },
  password: {
    type: String,
    required: true,
  },
  date: {
    type: Date,
    default: Date.now,
  },

I have tried various queries and aggregation functions but I am not able to get the right solution for that. Is there another way to do get the list. I want to get a list of users and total likes they got in all their posts combined. How can I do that ?

2 Answers2

2

You can try this query

db.collection.aggregate([
  {
    $project: {
      user: 1,
      numberOfLikes: {
        $cond: {
          if: {
            $isArray: "$likes"
          },
          then: {
            $size: "$likes"
          },
          else: "NA"
        }
      }
    }
  }
])

You can find demo of this query here

Shivam
  • 3,514
  • 2
  • 13
  • 27
0

I recently have the same scenario, here's how I solved it:

I created 3 different Models. Users, Posts, Likes. The Post model will be:

 user: {
    type: Schema.Types.ObjectId,
  },
  text: {
    type: String,
    required: true,
  },
  imageURL: {
    type: [String],
  },
  name: {
    type: String,
    required: true,
  },
  category: {
    type: String,
  },
  date: {
    type: Date,
    default: Date.now,
  }

The Likes model:

postId: {
  type: Schema.Types.ObjectId,
  required: true
},
userId: {
  type: Schema.Types.ObjectId,
  required: true
},
likedBy: {
  type: Schema.Types.ObjectId,
  ref: 'User',
  required: true,
}
  1. While fetching the post, you can use aggregate function and fetch the likes with the post as shown here.
  2. If you want to fetch the number of likes the user has received, You can do it easily by: Like.find({userId}).countDocuments()

Avoid using arrays in such cases. Because there can be no limit for user likes. If your Application grows, managing likes this way would be a nightmare.