Сортировка мангуста по «Тренду»

#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 и разбить его на страницы? :/