MongoDB 来自多个模型/模式的查询和一个字段中的 return

MongoDB Query from multiple models / schemas and return in one field

我正在使用 Nodejs 和 MongoDB、mongoose 和 expressjs,创建了一个 Blog API 有用户、文章、喜欢和评论模式。以下是我使用的模式。


    const UsersSchema = new mongoose.Schema({
      username:        { type: String },
      email:           { type: String },
      date_created:    { type: Date },
      last_modified:   { type: Date }
    });


    const ArticleSchema = new mongoose.Schema({
      id:              { type: String, required: true },
      text:            { type: String, required: true }, 
      posted_by:       { type: Schema.Types.ObjectId, ref: 'User', required: true },
      images:          [{ type: String }],
      date_created:    { type: Date },
      last_modified:   { type: Date }
    });


    const CommentSchema = new mongoose.Schema({
      id:             { type: String, required: true },
      commented_by:   { type: Schema.Types.ObjectId, ref: 'User', required: true },
      article:        { type: Schema.Types.ObjectId, ref: 'Article' },
      text:           { type: String, required: true },
      date_created:   { type: Date },
      last_modified:  { type: Date } 
    });

我真正需要的是当我*获取文章集合时*我还想获取每篇文章的评论数。如何查询mongo?

由于需要查询多个集合,可以使用MongoDB的聚合。

此处:https://docs.mongodb.com/manual/aggregation/

示例:

Article
  .aggregate(
    {
      $lookup: {
        from: '<your comments collection name',
        localField: '_id',
        foreignField: 'article',
        as: 'comments'
      }
    },
    {
      $project: {
        comments: '$comments.commented_by',
        text: 1,
        posted_by: 1,
        images: 1,
        date_created: 1,
        last_modified: 1
      }
    },
    {
      $project: {
        hasCommented: {
          $cond: {
            if: { $in: [ '$comments', '<user object id>' ] },
            then: true,
            else: false
          }
        },
        commentsCount: { $size: '$comments' },
        text: 1,
        posted_by: 1,
        images: 1,
        date_created: 1,
        last_modified: 1
      }
    }
  )

聚合有点大,但让我试着解释一下: 首先我们需要过滤$lookup之后的评论。所以我们 $unwind 他们,让每篇文章只包含一个评论对象,所以我们可以使用 $match 进行过滤(这是过滤阶段,它的工作方式与 <Model>.find() 相同。过滤所需的用户后评论,我们再次 $group 一切,每个评论 $sum: 1,使用 grouper _id,文章的 _id。我们得到 $first 结果 $text, $images 等等。稍后,我们 $project 一切,但现在我们添加 hasCommented$cond,简单地做:如果 $comments 大于 0(用户有评论,所以这将是true,否则,false

MongoDB 的聚合框架非常棒,您几乎可以使用它对数据做任何您想做的事情。但请注意,有些东西可能比其他东西贵,请务必阅读参考资料。