Reputation: 2287
I have a collection of posts, and I would like to return them in order of 'trending'.
Currently, I'm returning them like so:
exports.list = async (req, res) => {
const posts = await Post.find({}).sort([['likes', -1], ['created', -1]]);
res.json(posts);
};
However, this isn't truly 'trending' posts as it's just returning posts in order of most likes and most recently created. Eg. something with 100 likes created over a year ago, is returned above a post created today with 99 likes. (This is more of a trending of all time method).
I'd like to achieve a way to return the recently created posts with high likes in descending order. Eg. a post with 100 likes created a year ago, is returned below a post with 99 likes created today.
Can I do this inside of mongoose .sort()
?
Edit:
// Sample Document
[
{
likes: 99,
views: 1,
_id: 5f9714d33ba3664e3a31b6d4,
title: 'test',
author:
{ _id: 5f7b085711ba55fb0413ccd4,
username: 'Tester',
__v: 0
},
text: 'test',
comments: [],
created: 2019-10-26T14:53:49.498Z
},
{
likes: 100,
views: 53,
_id: 5f9714d33ba3664e3a31b6c5,
title: 'test2',
author:
{ _id: 5f7b085711ba55fb0413ccd4,
username: 'Tester',
__v: 0
},
text: 'test',
comments: [],
created: 2020-10-26T18:26:27.498Z
},
]
Upvotes: 0
Views: 342
Reputation: 2287
Perhaps I didn't explain my question very well, but I did find a solution, posting it here in the hopes that It may help others.
In short, I created a trendScore
which is calculated by number of likes / (current date - date created)
, I then added the field to each post and then used the score to sort the order of posts.
exports.list = async (req, res) => {
const posts = await Post.aggregate([
{
$addFields: {
id: "$_id",
// I found that 'id' was renamed to '_id', so quick hack to insure existing codebase worked with this change.
trendScore: {
$divide: [ "$likes", {$subtract: [new Date(), "$created"]} ]
}
}
},
{
$sort: {
trendScore: -1
}
}
])
res.json(posts);
};
The request now returnes trending posts in descending order;
The method is there, although calculation could be improved. Hopefully it can be of some help. I would encourage anyone who uses this method to add a $limit as each time the request is made the trendScore is calculated.
Upvotes: 1