You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化MongoDB按外键ObjectId统计数量的GraphQL查询

优化GraphQL getChapters Resolver的N+1查询问题

原实现因循环每个Chapter调用Question.countDocuments产生N+1查询,性能低效,以下是两种高效优化方案:

方案1:批量统计问题数后关联章节数据

先通过聚合一次性统计所有(chapterRef, subjectRef)组合的问题数量,再查询章节数据并匹配统计结果,仅需2次数据库查询:

// 批量统计各章节对应的问题数量
const questionStats = await Question.aggregate([
  {
    $group: {
      _id: {
        chapterRef: "$chapterRef",
        subjectRef: "$subjectRef"
      },
      count: { $sum: 1 }
    }
  }
]);

// 转成映射表,快速查找对应统计值
const countMap = {};
questionStats.forEach(stat => {
  const key = `${stat._id.chapterRef}-${stat._id.subjectRef}`;
  countMap[key] = stat.count;
});

// 查询所有章节数据
const chapters = await Chapter.find({});

// 为每个章节追加问题数量字段
return chapters.map(chapter => {
  const key = `${chapter._id}-${chapter.subjectRef}`;
  return {
    ...chapter.toObject(),
    questionCount: countMap[key] || 0
  };
});

方案2:单次聚合查询完成所有操作

利用MongoDB的$lookup管道聚合,在查询章节的同时直接关联统计对应问题数量,仅需1次数据库查询:

const chapters = await Chapter.aggregate([
  // 关联questions集合并统计符合条件的问题数
  {
    $lookup: {
      from: "questions", // 对应Question集合的实际名称
      let: { chapterId: "$_id", subjectId: "$subjectRef" },
      pipeline: [
        {
          $match: {
            $expr: {
              $and: [
                { $eq: ["$chapterRef", "$$chapterId"] },
                { $eq: ["$subjectRef", "$$subjectId"] }
              ]
            }
          }
        },
        { $count: "total" }
      ],
      as: "questionCountTemp"
    }
  },
  // 提取统计结果,处理空值为0
  {
    $addFields: {
      questionCount: { $arrayElemAt: ["$questionCountTemp.total", 0] }
    }
  },
  {
    $set: {
      questionCount: { $ifNull: ["$questionCount", 0] }
    }
  },
  // 移除临时字段(可选)
  {
    $project: {
      questionCountTemp: 0
    }
  }
]);

// 转换为mongoose文档对象(按需选择)
return chapters.map(chapter => new Chapter(chapter));

优化说明

两种方案均将查询次数从N+1降至1或2次,大幅提升性能:

  • 方案1逻辑直观,适合需要单独复用问题统计数据的场景
  • 方案2用单次聚合完成所有操作,性能最优,推荐多数场景下使用

内容的提问来源于stack exchange,提问作者soubhagya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 20:57:27