如何编写猫鼬查询来组合来自两个模型的数据?

时间:2021-07-17 10:21:55

标签: javascript mongodb express mongoose mongodb-query

技术:MongoDB、ExpressJS

我有 3 个架构

  1. 用户架构:
userSchema = {
  name: {type: String},
  password: {type: String},
  email: {type: String},
  friends: {type: [mongoose.Types.ObjectId]}
}
  1. textPostSchema =
textPostSchema = {
   text: {type: String},
   postType: {type: String, default: "textPost"},
   userId: {type: mongoose.Types.ObjectId}
}
  1. articalPostSchema:
articalPostSchema = {
  title: {type: String},
  content: {type: String}
  postType: {type: String, default: "articalPost"},
  userId: {type: mongoose.Types.ObjectId}
}

现在我有一个社交媒体应用程序,当用户的朋友发布一个帖子时,我必须在其中显示这两个帖子,并包括无限滚动。 textPostarticalPost 都应该发送到前端,并且一次只能发送总共 10 个帖子。我应该如何为时间线编写 API?

输出应如下所示:

{
  post: [
          {
           title: "artical Post title", 
           content: "artical post content", 
           postType: "articalPost", 
           userId: "60b9c9801a2a2547de643ccd"
          },
          {
           text: "text post ", 
           postType: "textPost", 
           userId: "60b9c9801a2a2547de643ccd"
          }, 
          ... 8 more
        ]
}

更新: 我得到了解决方案:- 我创建了更多架构:

timelineSchema = {
    postId: {
      type: mongoose.Types.ObjectId,
      required: true,
      ref: function () {
        switch (this.postCategoryType) {
          case 'articleposts':
            return 'ArticlePost';
          case 'textposts':
            return 'TextPost';
        }
      },
    },
    postCategoryType: {
      type: String,
      required: true,
    },
    userId: {
      type: mongoose.Types.ObjectId,
      required: true,
      ref: 'User',
    },
  },

然后我创建了一个函数来只让朋友发帖:

exports.getTimelinePosts = async (req, res) => {
  try {
    const timelinePosts = await TimelineModel.find({
      userId: { $in: [...req.user.friends, req.params.id] },
    })
      .skip((req.params.page - 1) * 10)
      .limit(10)
      .sort({ createdAt: -1 })
      .populate('postId');
    return res.status(200).json({ status: 'success', data: timelinePosts });
  } catch (error) {
    return res.status(500).json(error);
  }
};

2 个答案:

答案 0 :(得分:1)

假设您使用的是 express 和 mongoose。获取两者的代码,

// first bring all those schema from your mongoose models
const Article = require('./models/ArticleSchema');
const Text = require('./models/TextSchema');

const fetchArticleAndTextPost = async (req, res)=>{
    //find all data 
    const articles = await Article.find();
    const texts = await Text.find();

    //join them together
    const post = articles.concat(texts);

    return res.status(200).json({
        status: 200,
        data: post,
    })

}

答案 1 :(得分:1)

要使用 Mongoose 实现分页,您可以这样做。

const getPosts = async (userId, pageNumber) => {
  let result = await Post.find({ userId })
    .skip((pageNumber - 1) * 10)
    .limit(10);

  return result;
};

pageNumber 是一个您需要从前端传递的计数器,每当用户达到滚动限制时,它就会增加 1。

如果您想查询和合并来自多个集合的数据,您需要更新架构以使用 populate。只需在您引用其他集合的地方包含 ref

这可能会有所帮助。 https://mongoosejs.com/docs/populate.html