ここで頭に浮かぶことの 1 つは、必要と思われるすべての作業を行う必要はないということです。問題は、おそらくTTL インデックスとキャップ付きコレクションの助けを借りて解決できるでしょう。次のエントリを検討してください。
{ "_id" : ObjectId("531cf5f3ba53b9dd07756bb7"), "user" : "A", "units" : 50 }
{ "_id" : ObjectId("531cf622ba53b9dd07756bb9"), "user" : "B", "units" : 62 }
したがって、2 つのエントリがあり、_id
挿入したときにその値が返されます。したがって、最初は「A」には相手がいませんでしたが、「B」のエントリはその前のエントリと対戦します。
ObejctId は単調です。つまり、「次の」オブジェクトの値は、常に最後のオブジェクトよりも大きくなります。挿入されたデータを使用して、次のようにします。
db.moves.find({
_id: {$lt: ObjectId("531cf622ba53b9dd07756bb9") },
user: { $ne: "B" }
}).limit(1)
これにより、直前に挿入された「移動」が現在の移動に与えられます。これは、以前に挿入されたものは現在のアイテムよりも値が小さい_id
ためです。また、ユーザー自身の動きに対して「遊んで」いないことを確認し、もちろん結果を 1 つのドキュメントのみに制限します。
したがって、「移動」は永遠に前進します。次の挿入がユーザー「C」によって行われると、ユーザー「B」から「移動」が取得され、ユーザー「A」はユーザー「C」から「移動」が取得されます。 "、 等々。
ここで「起こりうる」のは、「B」が次の「移動」を順番に行い、最後のリクエストと同じドキュメントを取得することだけです。しかし、それは「セッション」設計のポイントであり、最後の「結果」を保存し、同じものを返さないようにするためです。そのため、設計で必要に応じて処理します。
「遊ぶ」にはそれで十分なはずです。しかし、「削除」の部分に行きましょう。
当然のことながら、何かを削除したいと「考え」ますが、最初の「ヘルパー」に戻ると、これは必要ないはずです。以上のことから、削除は「クリーンアップ」の要因にすぎないため、コレクションが膨大な割合に成長することはありません。
TTL インデックスを適用した場合、このチュートリアルの説明とほぼ同じ方法で、コレクション エントリがクリーンアップされ、一定期間後に削除されます。
また、何ができるか、特にキーの増加する性質を使用していること、_id
およびこれが多かれ少なかれ本質的に「キュー」であることを考慮すると、これを上限付きコレクションとして適用できます。そのため、いつでも保持する「移動」の最大サイズを設定できます。
2 つを組み合わせると、特定のサイズまで「成長」し、アクティビティが少し遅くなった場合に自動的にクリーンアップされるものになります。これにより、すべての操作が高速に保たれます。
肝心なのは、あなたが心配していた「削除」の並行性が、再生されたばかりのドキュメントを削除する必要性を実際に「取り除く」ことによって取り除かれたということです。クエリはシンプルに保たれ、TTL インデックスと上限付きコレクションがデータ管理の面倒を見てくれます。
これで、「ブラインド ウォー」という非常に同時進行するゲームに対する私の見方がわかりました。