Dev Overflow Logo

Dev Overflow

Global search

Search across questions, answers, users and tags.

Loading...
save

Mongoose aggregation: how do I get a user's top tags?

clock icon

asked 2 months ago

message icon

1

eye icon

304

For a profile page I want the ten tags a user has posted under most often. Questions store tags as an array of ObjectIds. I can do it with a loop in JS, but that is a lot of round trips — can this be one aggregation?

1 Answer

Unwind, group, sort, then look up the names:

1Question.aggregate([
2 { $match: { author: new Types.ObjectId(userId) } },
3 { $unwind: "$tags" },
4 { $group: { _id: "$tags", count: { $sum: 1 } } },
5 { $sort: { count: -1 } },
6 { $limit: 10 },
7 {
8 $lookup: {
9 from: "tags",
10 localField: "_id",
11 foreignField: "_id",
12 as: "tag",
13 },
14 },
15 { $unwind: "$tag" },
16 { $project: { _id: "$tag._id", name: "$tag.name", count: 1 } },
17])
1Question.aggregate([
2 { $match: { author: new Types.ObjectId(userId) } },
3 { $unwind: "$tags" },
4 { $group: { _id: "$tags", count: { $sum: 1 } } },
5 { $sort: { count: -1 } },
6 { $limit: 10 },
7 {
8 $lookup: {
9 from: "tags",
10 localField: "_id",
11 foreignField: "_id",
12 as: "tag",
13 },
14 },
15 { $unwind: "$tag" },
16 { $project: { _id: "$tag._id", name: "$tag.name", count: 1 } },
17])

Sort and limit before the $lookup — otherwise you join every tag the user has ever touched and throw most of it away.

1

of 1

Write your answer here

Introduce the problem and expand on what you've put in the title.

Top Questions