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

MongoDB(mongoose/node)无需countDocuments、distinct统计唯一值数量

MongoDB 去重字段计数高效实现方案

1. 优先添加覆盖索引

你的聚合性能瓶颈90%以上来自没有匹配的索引,直接添加以下复合索引即可实现索引覆盖扫描,不需要回表查询原始文档,百万级数据下性能可提升5~10倍:

// mongoose 侧创建索引代码
YourModelSchema.index({ isSent: 1, documentStatus: 1, documentId: 1 });

如果其他计数规则用到其他过滤字段,可以把对应字段也加入索引,保证所有聚合的$match和$group用到的字段都在索引中即可。

2. 单聚合管道批量计算所有计数器

不要分开跑7~8次聚合请求,使用$facet阶段在单次聚合请求中完成所有计数统计,大幅减少数据库交互开销和重复数据扫描成本:

const stats = await YourModel.aggregate([
  // 第一步先过滤出所有计数规则覆盖的所有文档,缩小后续处理范围
  {
    $match: {
      $or: [
        { isSent: true, documentStatus: 'Sent' },
        { isRead: true, documentStatus: 'Read' },
        // 其他计数规则的过滤条件统一放这里
      ]
    }
  },
  // 多分支并行计算不同计数
  {
    $facet: {
      sentDocumentCount: [
        { $match: { isSent: true, documentStatus: 'Sent' } },
        { $group: { _id: '$documentId' } },
        { $count: 'count' }
      ],
      readDocumentCount: [
        { $match: { isRead: true, documentStatus: 'Read' } },
        { $group: { _id: '$documentId' } },
        { $count: 'count' }
      ]
      // 剩余其他计数规则按上面格式添加即可
    }
  }
]);

// 取值方式
const sentCount = stats[0].sentDocumentCount[0]?.count || 0;

3. 可选:低实时性场景加预缓存

如果计数统计对实时性要求不高(允许1~5分钟延迟),可以加定时任务定期跑聚合,把结果存在Redis或者专门的统计集合中,业务侧直接读缓存结果,响应速度可以到毫秒级。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 22:00:00