Yes, find-and-modify will solve your problem:
db.collection.findAndModify ({query: {isDone: false}, update: {$ set: {isDone: true}}, new: true, upsert: false # never create new documents});
This will return the one document that he just updated from false to true.
But you have a serious problem if your C ++ clients have ever had hiccups (the box dies, they are killed, the code has an error, etc.). Imagine that your TCP connection drops right after the update on the server, but before the C ++ code receives the job. It is usually better to have a multiphase approach:
change "isDone" to "isInProgress", then when this is done, delete the document. (Now you can see the stack of “todo” and “done.” If something is “done” for a long time, the client probably died.
change "isDone" to "phase" and atomically set it from "new" to "initial" (and then set to "finished"). Now you can see that something has been “running” for a long time, perhaps the client has died.
If you are really complex, you can make a partial index. For example, “Only index documents with“ phase: {$ ne: “completed”}. ”Now you do not need to waste space indexing millions of finished documents. The index contains only a few new / incomplete documents, so it is smaller / faster.
source share