首页 > 解决方案 > Mongoose 加载、限制和跳过两个集合中的数据

问题描述

我正在构建一个 MERN 堆栈社交媒体应用程序。在应用程序上,用户可以拥有一个带有帖子的个人资料,可以是照片或视频。

我的照片存储在帖子集合中,但是,视频存储在名为 media 的集合中。

当用户想要查看他们的帖子时,我有一个函数可以从两个集合中获取所有数据,按创建日期对它们进行排序并将它们返回到前端。在用户建立大量照片/视频之前,这一直运行良好,现在 MongoDB 将不再允许该用户发出请求,因为它占用了太多 RAM。

我想对此实现延迟加载,因此我不会请求用户甚至不需要的所有这些数据,并且我知道如何使用单个集合来执行此操作,但是,我不确定我会如何在使用两个集合时去做。

我知道我会一次将每个集合限制为 2 个对象,并为每个对象添加一个跳过以请求接下来的两个对象,但我不知道如何跟踪接下来需要哪些对象,照片或视频?

我当前的代码:

//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)
    })
  })
}

任何投入将不胜感激。

谢谢

标签: node.jsmongodbexpressmongoose

解决方案


您的 Post 和 Media 模式看起来非常相似。您应该考虑将它们合并到一个模式中。这将解决您的问题。

如果您不想更改架构,则应查看 mongodb聚合管道,该管道允许您连接来自多个集合的数据(使用$lookup)。


推荐阅读