Mongoose загружает, ограничивает и пропускает данные из двух коллекций

Я создаю приложение MERN для социальных сетей. В приложении у пользователя может быть профиль с постами, который может быть фото или видео.

Мои фотографии хранятся в коллекции сообщений, однако видео хранятся в коллекции с именем media.

Когда пользователь хочет просмотреть свои сообщения, у меня есть функция, которая получает все данные из обеих коллекций, сортирует их по дате создания и возвращает их во внешний интерфейс. Это работало нормально, пока пользователь не создал большое количество фотографий / видео, и теперь MongoDB больше не будет позволять этому пользователю делать запрос, поскольку он занимает слишком много оперативной памяти.

Я хочу внедрить в него ленивую загрузку, чтобы не запрашивать все эти данные, которые даже не нужны пользователю, и я знаю, как это сделать, используя одну коллекцию, однако я не уверен, как бы делать это при использовании двух коллекций.

Я знаю, что я бы ограничил каждую коллекцию двумя объектами одновременно и добавил бы пропуск для каждого из них, чтобы запросить следующие два объекта, но я не знаю, как отследить, что должно быть дальше: фотография или видео?

Мой текущий код:

//First function, called by route
const listPostAndMediaByUser = (req, res) => {
  sortMediaAndPosts(req)
    .then(function(postsAndMedia) {
      return res.json(postsAndMedia);
    })
    .catch(function(error) {
      console.log("Error getting posts", error)
      return res.status(400).json({
        error: errorHandler.getErrorMessage(error)
      });
    });
};

//Sorting function
//This function runs getPosts, and getMedia
//And sorts them by their creation date
const sortMediaAndPosts = function(req) {
  return new Promise(async function(resolve, reject) {
    let postsAndMedia = [];
    try {
      const posts = await getPosts(req);
      const media = await getMedia(req);
      postsAndMedia = [...posts, ...media].sort(
        (a, b) => new Date(b.created) - new Date(a.created)
      );
    } catch (error) {
      console.log('Error: ', error);
      reject(error);
    }
    resolve(postsAndMedia);
  });
};

//Get posts function
const getPosts = function(req) {
  return new Promise(async function(resolve, reject) {
    try {
      Post.find({ postedBy: req.profile._id })
        .limit(2)
        .select('-photo')
        .populate('postedBy', '_id name')
        .populate('comments.postedBy', '_id name')
        .sort('-created')
        .exec((err, posts) => {
          if (err) reject(err);
          else resolve(posts);
        });
    } catch(e) {
      console.log('error!', e)
      reject(e);
    }
  });
};

//Get Media function
const getMedia = function (req) {
  return new Promise(async function(resolve, reject) {
    Media.find({postedBy: req.profile._id})
    .limit(2)
    .populate('postedBy', '_id name')
    .populate('comments.postedBy', '_id name')
    .sort('-created')
    .exec((err, media) => {
      if(err) reject(err)
      else resolve(media)
    })
  })
}

Любой вклад будет принята с благодарностью.

Благодарность

Всего 1 ответ


Ваши схемы для Post и Media выглядят очень похоже. Вы должны рассмотреть возможность объединения их в единую схему. Это решит вашу проблему.

Если вы не хотите изменять свою схему, вы должны изучить конвейер агрегации mongodb, который позволяет объединять данные из нескольких коллекций (используя $ lookup ).


Есть идеи?

10000