Spring Boot中如何让MongoDB自增ID序列从指定数值开始递增
问题原因
inc操作符的第二个参数是序列每次递增的步长,你将其改为100相当于每次序列值加100,自然会出现100、200、300的结果,不符合每次步长为1的需求。
原有逻辑中序列默认从1开始的原因是:首次调用方法时,upsert:true会新建序列文档,MongoDB对不存在的seq字段执行inc("seq",1)时,默认从0开始累加,最终得到初始值1。
解决方案
可以借助MongoDB的setOnInsert操作符实现需求:该操作符仅在upsert触发新建文档时生效,已有文档更新时不会执行,完全适配首次初始化和后续递增两个场景。
调整逻辑:
- 步长保持为1不变,保证每次序列只加1
- 新增
setOnInsert配置,首次新建文档时将seq初始值设为99,累加1之后刚好得到100的起始值 - 注意修正原代码中参数名大小写不一致的拼写错误(方法参数是
seqname,查询条件用了seqName)
修改后代码:
public int generateSeq(String seqName) { // 修正参数名大小写统一 Query query = new Query(Criteria.where("_id").is(seqName)); Update update = new Update() .setOnInsert("seq", 99) // 仅新建文档时生效,设置初始值为99 .inc("seq", 1); // 步长保持1不变 DbSeq counter = mongoOperations.findAndModify(query, update, options().returnNew(true).upsert(true), DbSeq.class); return !Objects.isNull(counter) ? counter.getSeq() : 100; // 默认值同步改为100 }
可选替代方案(无需改代码)
如果不想修改代码,可以提前在MongoDB对应的序列集合中手动插入对应序列名的初始化数据:
// 进入MongoDB shell执行,替换your_seq_name为实际的序列名 db.dbSeq.insert({_id:"your_seq_name", seq:99})
插入后原代码无需任何修改,首次调用inc("seq",1)就会得到100,后续正常按步长1递增。
内容的提问来源于stack exchange,提问作者LazyGuy
相关产品推荐
相关产品推荐

