【问题标题】:mongodb aggregate $lookup vs find and populatemongodb 聚合 $lookup 与查找和填充
【发布时间】:2019-10-25 14:51:23
【问题描述】:

我有一个像这样的视频架构:

const VideoSchema = new mongoose.Schema({
  caption: {
    type: String,
    trim: true,
    maxlength: 512,
    required: true,
  },
  owner: {
    type: mongoose.Schema.ObjectId,
    ref: 'User',
    required: true,
  },
  // some more fields
  comments: [{
    type: mongoose.Schema.ObjectId,
    ref: 'Comment',
  }],
  commentsCount: {
    type: Number,
    required: true,
    default: 0,
  },
}, { timestamps: true });

还有一个像这样的简单评论模式:

const CommentSchema = new mongoose.Schema({
  text: {
    type: String,
    required: true,
    maxLength: 512,
  },
  owner: {
    type: mongoose.Schema.ObjectId,
    ref: 'User',
    required: true,
  },
  videoId: {
    type: mongoose.Schema.ObjectId,
    ref: 'Video',
    required: true,
    index: true,
  },
}, { timestamps: true });

通过这样的架构,我可以对我的视频集合执行任何类型的查找查询并使用其 cmets 填充它:

Video.find({ owner: someUserId }).populate({ path: 'comments' });

我的问题是在视频集合中保留评论 ID 有多大必要?鉴于我已经在我的 Comment 模式中索引了 videoId 字段,摆脱这些评论 id 和它们的数量并使用聚合 $lookup 来查找视频的 cmets 会有多糟糕(谈到性能):

Video.aggregate([
  {
    $match: {
      owner: someUserId,
    },
  },
  {
    $lookup: {
      from: 'comments',
      localField: '_id',
      foreignField: 'videoId',
      as: 'comments',
    }
  }
])

这些在性能方面有何不同?

【问题讨论】:

    标签: node.js mongodb mongoose aggregation-framework


    【解决方案1】:

    好吧,$lookup 不可能比在实际视频对象上拥有评论 ID 列表更快。我的意思是你现在必须向 mongo 发送whole other request 才能获得它们。所以性能明智显然查找会增加时间。这是假设您没有使用 mongoose populate 将这些评论 ID“转换”为引用的对象。

    如果您要从视频中删除 cmets(以及实际的计数道具)并进行查找,那么您可以这样做。由于您在 arg 中立即进行匹配,然后执行简单的 lookup,我不明白这对您来说是个瓶颈。您还可以通过 explain 等优化/更改/调整您的聚合。

    这样你的视频架构会很干净:

    const VideoSchema = new mongoose.Schema({
      caption: {
        type: String,
        trim: true,
        maxlength: 512,
        required: true,
      },
      owner: {
        type: mongoose.Schema.ObjectId,
        ref: 'User',
        required: true,
      },
      // some more fields
    }, { timestamps: true });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-14
      • 1970-01-01
      • 2020-08-19
      • 2021-04-11
      • 2022-01-05
      • 2021-10-22
      • 1970-01-01
      • 2017-10-08
      相关资源
      最近更新 更多