2011-12-05 13 views
6

私は分析システムを作成していますが、APIコールは一意のユーザーIDを提供しますが、順不同ではありません。MongoDBで一意のユーザーIDのシーケンスを格納するための自動インクリメント

ビットマップ/ビットセット内の分析データポイントをマークするために、各ユニークユーザーIDに自動インクリメントIDを与える必要があります。したがって、最初のユーザー遭遇はビット配列の最初のビットに対応し、2番目のユーザーはビット配列の2番目のビットになります。

MongoDBでインクリメンタルユニークユーザーIDを生成するための確かな方法がありますか? Mongoの中

+0

私はあなたのような同じ問題を、ビットセットの位置を設定するIDを生成する方法を満たしています。あなたはこの問題を解決しましたか? – brucenan

答えて

5

することができますが、あなたは http://www.mongodb.org/display/DOCS/How+to+Make+an+Auto+Incrementing+Field

いけない各オブジェクトには、すでにIDを持っている、と彼らは、挿入順でソート可能です。ユーザオブジェクトのコレクションを取得し、それを反復処理し、インクリメントされたIDとしてこれを使用すると何が問題になりますか?あなたは完全にmap-reduceジョブを手に入れます。

+0

問題は並列です。 iterateは重複したインクリメンタルIDを発行します。 – est

+0

このIDは、データの保存ではなく解析にのみ必要です。 IIUCでは、配列のインデックスとしてのみシーケンシャルIDが必要なので、ビットセットを構築できます。この増分IDをデータベースに保存せずに達成することができ、クライアントにデータを取得せずにビット配列を構築することができます –

+0

毎回反復でincr IDを取得するのは賢明ではありません。特に、データポイントごとに何百万人ものユーザーを扱います。ドンMAUは30倍の反復を必要とするでしょう。 – est

11

答えとして、findAndModifyを使って順次IDを生成できます。

しかし、私はあなたがそれをすべきではないという意見に強く反対します。それはすべてあなたのビジネスニーズに依存します。 12バイトのIDを持つことは、非常にリソースを消費し、今後大きなスケーラビリティの問題を引き起こす可能性があります。

詳細な回答はhereです。私は次のように使用することをお勧め

+0

これはmongoの組み込み機能で、 '.createIndex({" number ":1}、{unique:true})'はインクリメントを表し、そうでなければ-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()を。()+ 1カウント)私の必要性のために働きました。

+14

これを想像してみてくださいあなたは5つのレコードを持っています。次のIDは6である必要がありますが、レコードを削除しました。 3.シーケンス1,2,4,5があります。あなたのやり方では、次のIDは5です(count = 4 + 1なので)。最終的には1,2,4,5,5となります。 –

4

最初に、すべてのシーケンスフィールドの最後のシーケンス値を記録するカウンタカウンタを作成します。

 db.createCollection("counters") 

カウンターのコレクションにこのシーケンスの文書を挿入するには、次のコードを使用する - JavaScript関数を作成

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

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)、および角度(フロントエンドWebアプリケーション)で中規模から大規模なCRMを構築していますが、特定のエンティティを選択するために角度ルーティングでは非常に恐ろしいObjectIdが見つかりました。 APIコントローラのルーティングと同じです。

上記の提案は、私のプロジェクトでは完璧に機能しました。

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

それは私の場合に最適です理由はなく、すべてのケースでは、コレクションから3つのレコードを削除する場合は、上記のコメントの状態として、あなたが衝突を取得することです。

私のビジネスルールでは、当社の社内SLAのために、私が書いているアプリケーションの潜在的寿命より長い間、連絡文書データやクライアントレコードを削除することは許可されていないと述べています。 enum "Status"は "Active"または "Deleted"のいずれかです。 UIから何かを削除することができますが、「連絡先は削除されました」と表示されますが、すべてのアプリケーションが完了したことは連絡先のステータスを「削除済み」に変更することです。データをクライアントアプリケーションにプッシュする前に削除されたレコードを削除します。

したがって、db.collection.find()。1 +)(カウントそれは皆のため動作しません...

私のための完璧なソリューションですが、データを削除しない場合、それ正常に動作します。

+0

には、mongodbがdb.xxx.find.count + 1のようなソートではなく、関数とカウンターシーケンスを使用しなければならないという特別な理由がありますか?いろいろなことが起こっているのでしょうか?あなたのソリューションはウェブサーバ環境でうまく機能しますか? – ckinfos

+0

これは並行セットアップではうまくいかないでしょう。あなたが同時にカウントをした場合、同じ_idを持つドキュメントを簡単に得ることができます。 – zephos2014

関連する問題