如何将MongoDB的Hash类型_id替换为自增简单整数ID?
MongoDB 自定义自增整数_id实现方案
完全可以将默认的ObjectId替换为自增整数类型的_id,MongoDB允许自定义_id字段的值,无需使用默认生成的哈希格式ObjectId。
官方推荐实现方式:计数器集合方案
该方案通过原子操作保证并发场景下ID不会重复,适配绝大多数业务场景:
- 创建专门存储计数器的集合,记录每个业务集合当前的最大ID值
// 初始化用户ID计数器,初始值设为0 db.counters.insertOne({ _id: "user_id", sequence_value: 0 })
- 定义原子获取下一个ID的工具函数
function getNextUserId() { const res = db.counters.findOneAndUpdate( { _id: "user_id" }, { $inc: { sequence_value: 1 } }, // 原子递增1 { returnNewDocument: true } ); return res.sequence_value; }
- 新增用户时手动赋值
_id即可
// 插入后_id自动为1、2、3依次递增 db.users.insertOne({ _id: getNextUserId(), username: "测试用户", phone: "13xxxxxxxxx" })
Mongoose 生态简化方案
如果你使用Mongoose操作MongoDB,可以直接用mongoose-auto-increment插件实现,无需手动维护计数器:
const mongoose = require('mongoose'); const autoIncrement = require('mongoose-auto-increment'); // 初始化插件 autoIncrement.initialize(mongoose.connection); // 定义用户Schema const userSchema = new mongoose.Schema({ username: String, email: String }); // 绑定自增配置,指定_id从1开始递增 userSchema.plugin(autoIncrement.plugin, { model: 'User', field: '_id', startAt: 1 }); const User = mongoose.model('User', userSchema);
后续新建用户直接保存即可,_id会自动生成递增整数。
注意事项
- 禁止通过查询当前集合最大
_id再加1的方式生成ID,高并发场景下会出现ID重复问题,必须使用原子递增操作。 - 默认ObjectId自带生成时间、节点标识等信息,排查问题时更便捷,替换为自增ID后会丢失该特性,可根据业务需求权衡选择。
- 分片集群场景下使用该方案需要额外适配,单实例、副本集场景下可直接使用上述方案。
内容的提问来源于stack exchange,提问作者user14305816
相关产品推荐
相关产品推荐

