2011-12-05 48 views
6

我正在製作一個分析系統,API調用將提供一個唯一用戶ID,但它不是按順序,也不是太稀疏。在MongoDB中自動遞增以存儲唯一用戶ID序列

我需要爲每個唯一用戶ID分配一個自動增量ID以標記位數組/位組中的分析數據點。因此,第一個用戶遇到的將對應於bitarray的第一位,第二個用戶將是bitarray中的第二位,等等。

那麼是否有一種可靠且快速的方式在MongoDB中生成增量唯一用戶ID?

+0

我遇到了和你一樣的問題,如何生成id來設置bitset的位置。你解決了這個問題嗎? – brucenan

回答

5

可以,但你不應該 http://www.mongodb.org/display/DOCS/How+to+Make+an+Auto+Incrementing+Field

在蒙戈每個對象已經有一個ID,他們是按插入順序排序。獲取用戶對象的集合有什麼問題,迭代它並將其用作遞增的ID?呃去完整的地圖減少作業

+0

問題是併發的。迭代會發出重複的增量ID。 – est

+0

您只需要此ID用於分析,而不是數據存儲。 IIUC,你只需要順序ID作爲你的陣列的索引,所以你可以建立bitset。您可以在不將數據庫中的此增量ID存儲的情況下實現該功能,並且可以在不向客戶端檢索數據的情況下構建位陣列。 –

+0

每次都通過迭代獲取incr ID非常不明智,特別是每個數據點處理數百萬個用戶。 Dong a MAU需要30次迭代。 – est

11

作爲選定的答案說,你可以使用findAndModify產生序列ID。

但我強烈反對意見,你不應該這樣做。這一切都取決於您的業務需求。擁有12字節的ID可能非常耗費資源,並且將來會導致顯着的可擴展性問題。

我有詳細答案here

+0

你可以,如果你想,我也不同意,因爲這是'.createIndex({「number」:1},{unique:true})'mongo內置功能,其中1表示增量,否則爲-1 –

-5

我建議您使用以下......它爲我:)

db.master.insert({ 
    "id": db.master.find().count()+1, 
    "ip": "123.456.789.101", 
    "port": "19132", 
    "api-key": "1234", 
    "name": "TEST "+(db.master.find().count()+1) 
}) 

使用(db.master.find()。COUNT()+ 1)就職於我的需要。

+14

想象一下你有5條記錄。下一個ID必須是6,但您刪除了一些記錄,例如3.現在你有序列1,2,4,5。在你的方式下,下一個ID將是5(因爲count = 4 + 1)。最終排名將是1,2,4,5,5。 –

4

首先創建一個計數器集合,它將跟蹤所有序列字段的最後一個序列值。

 db.createCollection("counters") 

使用下面的代碼在櫃檯集合插入此序列文件 -

db.counters.insert({_id:"tid",sequence_value:0}) 

創建JavaScript函數:

function getNextSequenceValue(sequenceName){ 
     var sequenceDocument = db.counters.findAndModify({ 
     query:{_id: sequenceName }, 
     update: {$inc:{sequence_value:1}}, 
     new:true 
      }); 
     return sequenceDocument.sequence_value; 
     } 

插入兩個文件:

  db.products.insert({ 
      "_id":getNextSequenceValue("tid"), 
      "product":"Samsung", 
      "category":"mobiles" 
      }) 


      db.products.insert({ 
      "_id":getNextSequenceValue("tid"), 
      "product":"Samsung S3", 
      "category":"mobiles" 
       }) 

得到插入文件:

  db.prodcuts.find() 

OUTPUT

{ 「_id」:1, 「產品」: 「三星」, 「類別」: 「移動設備」}

{ 「_id」:2 ,「產品」:「三星S3」,「類別」:「手機」}

3

我知道這是一個老問題,但我會後我留給後人的答案...

這取決於SY因爲你正在建立並制定特定的業務規則。

我在MongoDb,C#(後端API)和Angular(前端Web應用程序)中構建了一箇中等規模的大型CRM,並發現ObjectId在Angular Routing中用於選擇特定實體非常可怕。與API控制器路由一樣。

上述建議對我的項目非常合適。

db.contacts.insert({ 
"id":db.contacts.find().Count()+1, 
"name":"John Doe", 
"emails":[ 
    "[email protected]", 
    "[email protected]" 
], 
"phone":"555111322", 
"status":"Active" 
}); 

的原因,它是非常適合我的情況,但並非所有的案件是,對於與上述評論的狀態,如果從集合中刪除3條記錄,你會得到碰撞。

我的業務規則規定,由於我們內部的SLA的原因,我們不允許刪除通信數據或客戶記錄的時間超過我正在編寫的應用程序的潛在使用期限,因此,我只是用枚舉「狀態」,即「活動」或「已刪除」。您可以從UI中刪除某些內容,並且它會顯示「聯繫人已被刪除」,但所有應用程序已完成將聯繫人的狀態更改爲「已刪除」,並且當應用程序調用聯繫人列表的儲存庫時,我會過濾將數據推送到客戶端應用程序之前刪除已刪除的記錄。

因此,db.collection.find()。COUNT()+ 1對我來說是完美的解決方案......

它不會對每個人都有效,但如果你將不會被刪除的數據,它工作正常。

+0

是否有任何特殊的原因,mongodb聲明你必須使用函數和計數器序列,而不是db.xxx.find.count + 1的靈魂?是否可能通過處理弄亂事物?你的解決方案在Web服務器環境中運行良好嗎?謝謝你的回答 – ckinfos

+0

這並不是一個好的併發設置。如果他們同時進行計數,則可以輕鬆獲得具有相同_id的文檔。 – zephos2014