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

Posted

技术标签:

【中文标题】如何编写猫鼬查询来组合来自两个模型的数据?【英文标题】:How to write mongoose query to combine data from two model's? 【发布时间】:2021-09-25 21:12:33 【问题描述】:

技术:MongoDB、ExpressJS

我有 3 个架构

    用户架构:
userSchema = 
  name: type: String,
  password: type: String,
  email: type: String,
  friends: type: [mongoose.Types.ObjectId]

    textPostSchema =
textPostSchema = 
   text: type: String,
   postType: type: String, default: "textPost",
   userId: type: mongoose.Types.ObjectId

    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);
  
;

【问题讨论】:

您想在一个帖子对象中合并文章帖子架构和文本帖子架构? @AbuSayeedMondal 是的,您可以说,每次我调用 API 获取帖子时,API 都应该响应下一个 10 个帖子,这 10 个帖子应该属于 textPost 或 articlePost 或两者都根据@ 987654329@. 【参考方案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

【讨论】:

感谢 Uddesh,让我实现这个,如果一切顺利,我会告诉你!!【参考方案2】:

假设您使用的是 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,
    )



【讨论】:

我想创建一次发送 10 个帖子的 api,它将连接所有帖子并将数据发送回前端。如果我们有 10000 条文章帖子和 10000 条文本帖子,那么这个代码复杂度太高了。而且我们不能在concat 之后拼接我们的数组,因为我们只需要在前一个帖子之后发布 10 个帖子,因此剩余的数据是无用的。有什么方法可以一次从两个模型中提取 10 个帖子?

以上是关于如何编写猫鼬查询来组合来自两个模型的数据?的主要内容,如果未能解决你的问题,请参考以下文章

关于如何在猫鼬中编写评论模式的任何想法?

关于如何在猫鼬中编写评论模式的任何想法?

如何编写从两个搜索值返回匹配项的 sql 查询

通过猫鼬中的两个值查找数据

EJS:如何在 EJS 文件中呈现来自猫鼬的两个或多个填充集合

如何使用猫鼬羽毛适配器编写聚合?