I have a mongodb collection of tasks with documents looks like:
id: objId
retries: Int
status: String
lockedUntill: ISO time
Retries can be Integers from 1 to 10
statuses can be: READY, AWAIT, FAILED, DONE, etc..
I'm using scala with ReactiveMongo and I want to search for 1 doc at a time in status READY
and change its lockedUntil based on the number of retries and return the new document.
For example: if:
- the doc is not locked(task.lockedUntil: {$lt:
now}), - the doc status is ready(task.status:
READY) and than some switch that is based on the Int in the retries I will set the locked until. for example{$eq: {$task.retries: 2}}thanconfig.secondLockedUntill
This is the query that is working directly to the db.
db.tasks.findOneAndUpdate({ "_id": ObjectId("bla") }, [{
$set: {
"task.lockedUntil": {
$switch: {
branches: [
{ case: { $eq: ["$task.retries", 1] }, then: "" },
{ case: { $eq: ["$task.retries", 2] }, then: "READY2" },
{ case: { $eq: ["$task.retries", 3] }, then: "READY3" },
{ case: { $eq: ["$task.retries", 4] }, then: "READY4" },
],
default: "default value"
}
}
}
}])
Now I'm tring to convert that to scala and ReactiveMongo code and getting a lot of issues.
Sometimes with js parsing and sometimes with ReactiveMongo operators not supporting aggregation pipline.
collection.findAndUpdate is not supporting aggregation pipeline and update
update.one is not returning the document.
Any ideas? Is it possibe or I have to split it to multiple operations?
You can use
collection.aggregationUpdateModifier(updateAggPipeline, fetchNewBool, upsertBool)in combination withcollection.findAndModify(selector, updateModifier)