非Mongo Atlas环境下MongoDB实现自增字段的解决方案咨询
MongoDB 本地部署环境实现字段自增的可行方案
以下方案均无需依赖Mongo Atlas的Trigger功能,适配所有本地部署的MongoDB环境,可直接在Node.js后端项目中使用:
方案1:使用独立计数器集合(原生MongoDB支持,无第三方依赖,推荐生产环境使用)
原理是单独维护一个计数器集合,通过原子操作读取并更新当前最大序号,避免并发冲突,所有MongoDB版本均支持:
- 第一步:创建计数器集合并初始化初始值
执行Mongo命令:db.counters.insertOne({ _id: "yourBizField", sequence_value: 0 })
其中_id为业务标识,比如要给订单表的orderId做自增就填orderId,给用户表的userId做自增就填userId - 第二步:封装原子获取自增序号的方法
Node.js中调用示例:async function getNextSequenceValue(sequenceName) { const sequenceDoc = await db.collection('counters').findOneAndUpdate( { _id: sequenceName }, { $inc: { sequence_value: 1 } }, { returnDocument: "after", upsert: true } ); return sequenceDoc.sequence_value; } - 第三步:插入业务文档时调用方法即可
await db.collection('orders').insertOne({ orderId: await getNextSequenceValue('orderId'), productName: "测试商品", amount: 99 })
该方案为原子操作,支持高并发场景,是官方推荐的非Atlas环境自增字段实现方式
方案2:使用Mongoose自增插件(适用于Node.js项目用Mongoose ODM的场景)
如果项目已经使用Mongoose连接MongoDB,可以直接用成熟插件实现,无需手动写计数器逻辑:
- 第一步:安装插件:
npm install mongoose-auto-increment - 第二步:初始化插件
const mongoose = require('mongoose'); const autoIncrement = require('mongoose-auto-increment'); // 数据库连接建立后初始化 autoIncrement.initialize(mongoose.connection); - 第三步:给业务Schema配置自增字段
const orderSchema = new mongoose.Schema({ productName: String, amount: Number }); // 配置orderId为自增字段,起始值1,步长1 orderSchema.plugin(autoIncrement.plugin, { model: 'Order', field: 'orderId', startAt: 1, incrementBy: 1 }); const Order = mongoose.model('Order', orderSchema); - 第四步:直接插入文档即可,插件会自动生成自增字段:
new Order({productName:"测试商品", amount:99}).save()
方案3:自定义Pre-save钩子实现(仅适合低并发小型项目)
如果不想引入第三方依赖,也可以自己写Mongoose预保存钩子实现:
orderSchema.pre('save', async function(next) { if (this.isNew) { // 查询当前集合最大的orderId,加1后赋值给新文档 const maxDoc = await this.model('Order').findOne().sort({orderId: -1}).exec(); this.orderId = maxDoc ? maxDoc.orderId + 1 : 1; } next(); })
注意该方案未做并发控制,高并发插入时可能出现重复序号,不建议生产环境使用
内容的提问来源于stack exchange,提问作者D. Barman
相关产品推荐
相关产品推荐

