两种计数怎么选
MongoDB 提供两种计数方式:countDocuments(filter) 精确统计满足条件的文档数,estimatedDocumentCount() 读取集合元数据估算总量、不扫描文档,速度更快但可能有偏差。旧的 count() 已被标记为不推荐使用,新代码应改用前两个方法。
基本信息
| 精确计数 | db.collection.countDocuments(filter) |
|---|---|
| 估算计数 | db.collection.estimatedDocumentCount(),不接受过滤条件 |
| 旧方法 | count() 已不推荐,新代码不要继续使用 |
| 性能关键 | countDocuments 会走查询计划,条件命中索引时通常很快 |
| 分布式影响 | 分片集合上精确计数需要各分片汇总,成本随分片数上升 |
典型使用场景
- 分页展示总数:需要准确值时用 countDocuments
- 巡检摸清规模:用 estimatedDocumentCount 快速了解集合体量
- 条件统计:按状态或时间范围统计文档数
- 对账与监控:比对实际数量与业务预期是否一致
- 交叉验证:用 countDocuments 核对聚合分组的结果
常用写法
常用写法
// 精确计数
db.orders.countDocuments({ status: "paid" })
// 估算总量:读元数据,不扫描文档,也不接受过滤条件
db.orders.estimatedDocumentCount()
// 聚合里的等价统计,条件复杂时更好用
db.orders.aggregate([{ $match: { status: "paid" } }, { $count: "paidCount" }])
// 按状态分组后分别计数
db.orders.aggregate([{ $group: { _id: "$status", n: { $sum: 1 } } }])两种计数对照
| 对比项 | countDocuments | estimatedDocumentCount |
|---|---|---|
| 准确性 | 精确 | 可能有偏差 |
| 过滤条件 | 支持 | 不支持 |
| 实现方式 | 走查询计划扫描匹配文档 | 读集合元数据计数 |
| 分片集合 | 各分片汇总后合并 | 分片场景下偏差更明显 |
| 典型用途 | 分页总数、对账 | 巡检与容量摸底 |
countDocuments 会走查询计划,条件命中索引时通常很快;无条件地对超大集合做精确计数反而容易变成慢查询,巡检场景优先用 estimatedDocumentCount。
分页接口不一定需要精确总数:多取一条来判断是否还有下一页即可,可以省掉一次全集合计数;确实要展示总数时,把计数结果按秒级缓存,避免每个请求都重新统计。