はい、検索と変更で問題が解決します。
db.collection.findAndModify( { query: { isDone: false }, update: { $set: { isDone: true } }, new: true, upsert: false # 新しいドキュメントを作成しない } );
これにより、false から true に更新されたばかりの単一のドキュメントが返されます。
しかし、C++ クライアントに問題が発生した場合 (ボックスが停止する、強制終了される、コードにエラーが発生するなど)、重大な問題が発生します。サーバーの更新直後で、C++ クライアントが更新される前に、TCP 接続が切断された場合を想像してみてください。コードが機能します。一般に、マルチフェーズ アプローチを採用することをお勧めします。
「isDone」を「isInProgress」に変更し、完了したらドキュメントを削除します。(これで、"todo" と "beulding" のスタックが表示されます。何かが長時間 "doed" されている場合、クライアントは死亡した可能性があります。
「isDone」を「phase」に変更し、原子的に「new」から「started」に設定します(後で「finished」に設定します)。これで、何かが長時間「開始」されているかどうかを確認できます。クライアントが停止した可能性があります。
あなたが本当に洗練されているなら、部分的な索引を作ることができます。たとえば、「"phase:{ $ne: 'finished'}" のドキュメントのみをインデックス化します。これで、数百万の完成したドキュメントのインデックス作成にスペースを浪費する必要がなくなりました。インデックスは、少数の新規/進行中のドキュメントのみを保持します。 、したがって、より小さく/より高速です。