私は分析システムを作成していますが、API呼び出しは一意のユーザーIDを提供しますが、順序が正しくなく、まばらです。
Bitarray/bitsetの分析データポイントをマークするには、各一意のユーザーIDに自動インクリメントIDを与える必要があります。したがって、最初のユーザーはビット配列の最初のビットに対応し、2番目のユーザーはビット配列の2番目のビットになります。
それでは、MongoDBでインクリメンタルユニークユーザーIDを生成するための確実で高速な方法はありますか?
Mongoの各オブジェクトにはすでにIDがあり、挿入順にソートできます。ユーザーオブジェクトのコレクションを取得し、それを反復処理し、これを増分IDとして使用することの何が問題になっていますか? Erは完全に一種のmap-reduceジョブに行きます
選択した答えにあるように、findAndModifyを使用してシーケンシャルIDを生成できます。
しかし、私はあなたがそうすべきではないという意見に強く反対します。それはすべて、ビジネスニーズによって異なります。 12バイトのIDを持つことは、非常にリソースを消費し、将来的に大きなスケーラビリティの問題を引き起こす可能性があります。
詳細な答えがあります here .
最初にcountersコレクションを作成します。これは、すべてのシーケンスフィールドの最後のシーケンス値を追跡します。
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;
}
2つのドキュメントを挿入します。
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、「product」:「Samsung」、「category」:「mobiles」}
{"_id":2、 "product": "Samsung S3"、 "category": "mobiles"}
これは古い質問ですが、後世のために答えを投稿します...
構築しているシステムと特定のビジネスルールによって異なります。
MongoDb、C#(バックエンドAPI)、およびAngular(フロントエンドWebアプリ)で中規模から大規模のCRMを構築していますが、特定のエンティティを選択するためのAngularルーティングで使用するにはObjectIdが非常にひどいことがわかりました。 API Controllerルーティングと同じです。
上記の提案は、私のプロジェクトにとって完璧に機能しました。
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は私にとって完璧なソリューションです...
すべてのユーザーに有効ではありませんが、データを削除しない場合は正常に機能します。
最初のレコードを追加する必要があります
"_id" = 1 in your db
$database = "demo";
$collections ="democollaction";
echo getnextid($database,$collections);
function getnextid($database,$collections){
$m = new MongoClient();
$db = $m->selectDB($database);
$cursor = $collection->find()->sort(array("_id" => -1))->limit(1);
$array = iterator_to_array($cursor);
foreach($array as $value){
return $value["_id"] + 1;
}
}