標籤:
以下是官網原文地址:
http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/
概要
MongoDB 的_id欄位作為一個主鍵存在於所有文檔的最頂層,_id必須是唯一的,而且總是具有唯一約束的索引。除了唯一約束,你可以在集合中的_id欄位上使用任何值,
以下這個指南描述了在_id上建立一個自增序列的兩種方式:
Use Counter Collection
Optimistic Loop
注意事項
一般情況下,你不會願意在_id欄位,或任何欄位上使用自增模式,那是因為不會有大量的文檔構成的大規模資料庫,通常情況下,更為理想的是預設_id。
實現過程
Use Counter Collection
Counter集合實現:
利用一個單獨的計數器集合合去跟蹤我們使用的最後一個數字序列。該_id欄位包含了序列名稱和序欄欄位中該序列最後的值。
1、插入計數器集合合,設定初始值為userid:
db.counters.insert( { _id: "userid", seq: 0 })
2、建立一個getNextSequence函數,參數為序列的name,函數使用findandmodify()方法去自動成長序列的值並返回增長之後的結果:
function getNextSequence(name) { var ret = db.counters.findAndModify( { query: { _id: name }, update: { $inc: { seq: 1 } }, new: true } ); return ret.seq;}
3、在接下來插入資料的時候,使用getNextSequence這個函數:
db.users.insert( { _id: getNextSequence("userid"),//注意getNextSequence參數要與計數器集合合中_id值一致 name: "Sarah C." })db.users.insert( { _id: getNextSequence("userid"), name: "Bob D." })View Code
4、你可以試著查看結果:
db.users.find()
5、_id欄位包含了自動成長序列的值:
{ _id : 1, name : "Sarah C."}{ _id : 2, name : "Bob D."}
findandmodify這個方法包含了更新,查詢欄位並不是一定要有唯一索引,該方法可以在某些情況下多次插入同一個文檔。例如,有多個用戶端在使用同樣查詢條件時,都調用該方法,那麼調用這些方法在執行更新操作之前必須先完成查詢操作,而且這些方法能插入相同的文檔。
在計數器案例中,查詢欄位是_id欄位,它總是有一個獨立的索引。我們再看如下樣本:
function getNextSequence(name) { var ret = db.counters.findAndModify( { query: { _id: name }, update: { $inc: { seq: 1 } }, new: true, upsert: true } ); return ret.seq;}View Code
如果多個用戶端在傳入相同參數情況下來調用getNextSequence()方法,然後我們會發現以下其中一個行為將會發生:
一次findandmodify()方法將會成功插入一條文檔;
0個或多個findandmodify()方法將會更新新插入的檔案;
當它們試圖插入重複的資料時,0個或多個findandmodify()方法;
如果由於違反了唯一約束而導致方法失敗,請重試。
Optimistic Loop
略。
MongoDB整理筆記のID自增長