0

我正在使用Nodejs 和 MongoDB、mongoose 和 expressjs,创建一个包含用户、文章、喜欢和评论模式的博客 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?

4

1 回答 1

1

由于需要查询多个集合,可以使用 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 的聚合框架非常棒,你几乎可以使用它对数据做任何你想做的事情。但请注意,某些东西可能比其他东西花费更多,请务必阅读参考资料。

于 2019-01-22T22:54:49.223 回答