#mongodb #mongoose
#mongodb #мангуст
Вопрос:
У меня есть коллекция сообщений, и я хотел бы вернуть их в порядке «трендов».
В настоящее время я возвращаю их следующим образом:
exports.list = async (req, res) => {
const posts = await Post.find({}).sort([['likes', -1], ['created', -1]]);
res.json(posts);
};
Однако на самом деле это не «трендовые» сообщения, поскольку он просто возвращает сообщения в порядке наибольшего количества лайков и самых последних созданных. Например. что-то со 100 лайками, созданное более года назад, возвращается выше сообщения, созданного сегодня с 99 лайками. (Это скорее метод определения тенденций за все время).
Я хотел бы найти способ возвращать недавно созданные сообщения с высокими лайками в порядке убывания. Например. сообщение со 100 лайками, созданное год назад, возвращается под сообщением с 99 лайками, созданным сегодня.
Могу ли я сделать это внутри мангуста .sort()
?
Редактировать:
// 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
},
]
Комментарии:
1. но разве это не достигается просто заменой «созданных» и «лайков»? В любом случае, я бы объединил эти величины в 1 под названием «trendIndex» или что-то в этом роде.
2. можете ли вы опубликовать несколько примеров документов?
3. @Minsky это то, что я изначально думал, однако, если я поменяю их местами, он просто сортирует по дате и практически игнорирует лайки, если нет двух сообщений, созданных с одной и той же датой.
4. @wak786 добавлен к основному вопросу. Спасибо.
5.
sort({date: -1. likes:-1})
работает ли для вас?
Ответ №1:
Возможно, я не очень хорошо объяснил свой вопрос, но я нашел решение, разместив его здесь в надежде, что это может помочь другим.
Короче говоря, я создал trendScore
значение, которое вычисляется number of likes / (current date - date created)
, затем я добавил поле к каждому сообщению, а затем использовал оценку для сортировки порядка сообщений.
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);
};
Теперь запрос возвращает сообщения о трендах в порядке убывания;
- 1-е недавно добавленное и высокое количество лайков
- 2-й Не так недавно добавленный и высокий лайк
- 3-е недавно добавленное и низкое количество лайков
- 4-й Не так недавно добавленный и низкий лайк
Метод существует, хотя вычисление может быть улучшено. Надеюсь, это может помочь. Я бы посоветовал всем, кто использует этот метод, добавить ограничение в размере $, поскольку каждый раз, когда выполняется запрос, вычисляется trendScore.
Комментарии:
1. Спасибо, что поделились своим предложением, оно действительно было очень полезным. Однако это приводит к новому вопросу: как вы разбиваете это на страницы? если он разбит на страницы на основе поля $created, это было бы так же просто, как добавить $ lt: whatever_date, но что, если вы хотите сохранить этот trendingScore и разбить его на страницы? :/