欢迎您访问新疆栾骏商贸有限公司,公司主营电子五金轴承产品批发业务!
全国咨询热线: 400-8878-609

新闻资讯

技术学院

如何使用 Mongoose 统计集合中文档数量并生成自增 ID

作者:花韻仙語2026-01-07 00:00:00

本文介绍如何正确获取 mongodb 集合中文档总数,并基于该数值生成唯一、递增的 id,避免因误用 `findone()` 导致 `nan` 错误。

在构建类似“猜 Emoji”这类需要序号标识(如题号、关卡 ID)的应用时,开发者常希望通过统计已有文档数量来生成下一个自增 ID(例如:第 1 条记录 ID 为 1,新增后为 2)。但若错误地使用 model.findOne() 并对其结果调用 .length,会得到 undefined 或 NaN——因为 findOne() 返回的是单个文档对象(Object),而对象没有 .length 属性(数组才有),Object.length 恒为 undefined,参与数学运算即转为 NaN。

✅ 正确做法是使用 Mongoose 提供的聚合安全、高性能的计数方法:

// ✅ 推荐:使用 countDocuments()(推荐用于带条件或未来兼容性)
const count = await model.countDocuments(); // 返回 Promise
const newId = count + 1;

await model.create({ ID: newId });

⚠️ 注意事项:

  • ❌ 不要使用已弃用的 model.count()(Mongoose 7+ 中已移除),它易受查询条件影响且不支持 Promise 默认返回;
  • ✅ countDocuments() 是当前标准方法,支持链式查询(如 countDocuments({ status: 'active' })),且准确反映实际匹配文档数;
  • ⚠️ 在高并发场景下,countDocuments() + create() 非原子操作,存在极小概率 ID 冲突(如两个请求同时读到 count=5,均写入 ID=6)。如需强一致性 ID,建议:
    • 使用 MongoDB 原生 ObjectId(默认 _id 已具备时间序与唯一性);
    • 或引入独立计数器集合(通过 findOneAndUpdate(..., { upsert: true, new: true }) 实现原子自增);
    • 或改用数据库自增字段(如 PostgreSQL)或 Redis 序列器。

? 总结:findOne() 返回单文档对象,不可取 .length;统计文档数请始终使用 await model.countDocuments(),再进行逻辑计算。简洁、可靠、符合 Mongoose 最佳实践。