如何在MongoDB中使用id替代_id并实现id自增1、2、3、4?
实现MongoDB自增数字ID的方法
MongoDB默认使用ObjectId作为主键,要实现你需要的数字自增ID,基于Node.js + Mongoose的场景,常用以下两种可落地的方案:
方案1:使用mongoose-auto-increment插件(最简实现)
这是开发中最常用的快速实现方式,步骤如下:
- 先安装依赖:
npm install mongoose-auto-increment - 初始化插件和数据库连接
const mongoose = require('mongoose'); const autoIncrement = require('mongoose-auto-increment'); // 替换为你自己的MongoDB连接地址 const connection = mongoose.createConnection('mongodb://localhost:27017/你的数据库名'); // 绑定自增插件和数据库连接 autoIncrement.initialize(connection);
- 定义业务Schema并配置自增规则
const userSchema = new mongoose.Schema({ firstname: String, // 其他自定义字段 }, { timestamps: true }); // 开启timestamps后会自动生成createdAt、updatedAt字段,和你示例中的字段一致 // 配置自增规则 userSchema.plugin(autoIncrement.plugin, { model: 'User', // 对应你的模型名 field: 'id', // 自增字段名 startAt: 1, // 起始值为1 incrementBy: 1 // 每次自增步长为1 }); // 配置返回JSON时自动删除默认的_id字段,输出你需要的格式 userSchema.set('toJSON', { transform: function(doc, ret) { delete ret._id; // 如果不需要__v字段也可以加上 delete ret.__v; return ret; } }); const User = connection.model('User', userSchema);
后续调用new User().save()插入数据时,会自动生成自增的id字段。
方案2:手动维护自增序列(无需第三方依赖)
如果你不想引入额外插件,可以自己维护序列表实现自增,且是原子操作不会出现ID重复:
- 第一步:创建专门存储自增序列的集合
const counterSchema = new mongoose.Schema({ modelName: { type: String, required: true }, // 对应业务模型名 sequenceValue: { type: Number, default: 0 } // 当前序列最大值 }); const Counter = mongoose.model('Counter', counterSchema);
- 第二步:给业务Schema添加预插入钩子,自动生成自增ID
const userSchema = new mongoose.Schema({ id: { type: Number, unique: true }, firstname: String }, { timestamps: true }); // 新文档保存前自动获取自增ID userSchema.pre('save', async function(next) { // 仅新插入的文档生成ID,更新操作不触发 if (!this.isNew) return next(); try { // 原子性更新序列值,并发场景也不会重复 const counter = await Counter.findOneAndUpdate( { modelName: 'User' }, { $inc: { sequenceValue: 1 } }, { new: true, upsert: true } // 序列不存在时自动创建 ); this.id = counter.sequenceValue; next(); } catch (err) { next(err); } }); // 同样配置返回格式,删除默认_id userSchema.set('toJSON', { transform: (doc, ret) => { delete ret._id; return ret; } }); const User = mongoose.model('User', userSchema);
内容的提问来源于stack exchange,提问作者Nirodha Wickramarathna
相关产品推荐
相关产品推荐

