假設要爲CollectionB實現自增加ID, 須要引入另一個專門計算ID的CollectionA. A中存放一條記錄:{'_id':'CollectionB', 'currentIdValue':1}, 其中currentIdValue表示CollectionB的當前最大id值+1,每次往CollectionB裏插入數據前,先到CollectionA查詢currentIdValue 值並把這個值+1。mongodb
實現方式主要是利用MongoDB中findAndModify命令,只要每次往MongoDB裏insert對象前生成ID賦值給_id就OK了,由於它的實現知足原子性,因此不存在併發問題。findAndModify自己提供了一個upsert參數,爲true的話能夠自動insert,但那樣就不能自定義初始值了,因此不使用upsert。數據庫
另,數據庫「_seq」的名字如下劃線開頭,這樣列表的時候會排在前面,容易分辨。併發
實現步驟以下:ui
> db.CollectionA.insert({'_id':'CollectionB', 'currentIdValue':0}) WriteResult({ "nInserted" : 1 }) > > ID=db.CollectionA.findAndModify( {update:{$inc:{"currentIdValue":1}}, query:{"_id":"CollectionB"}, new:true} ) { "_id" : "CollectionB", "currentIdValue" : 1 } > > db.user.save( {_id:ID.currentIdValue, uid:ID.currentIdValue, username:"zhangsan", password:"password123", info:"Test User1"} ); WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > > ID=db.CollectionA.findAndModify( {update:{$inc:{"currentIdValue":1}}, query:{"_id":"CollectionB"}, new:true} ) { "_id" : "CollectionB", "currentIdValue" : 2 } > > db.user.save( {_id:ID.currentIdValue, uid:ID.currentIdValue, username:"lisi", password:"test1234567", info:"Test User2"} ); WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > > db.user.find() { "_id" : 1, "uid" : 1, "username" : "zhangsan", "password" : "password123", "info" : "Test User1" } { "_id" : 2, "uid" : 2, "username" : "lisi", "password" : "test1234567", "info" : "Test User2" } > > db.CollectionA.find() { "_id" : "CollectionB", "currentIdValue" : 2 } > > # 執行命令增長值 > db.runCommand({findAndModify:'CollectionA',query:{_id:'CollectionB'}, update:{$inc:{'currentIdValue':1}}, new:true}); { "lastErrorObject" : { "updatedExisting" : true, "n" : 1 }, "value" : { "_id" : "CollectionB", "currentIdValue" : 3 }, "ok" : 1 } > > db.CollectionA.find() { "_id" : "CollectionB", "currentIdValue" : 3 }