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}} than config.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?

1

There are 1 best solutions below

0
cchantep On

You can use collection.aggregationUpdateModifier(updateAggPipeline, fetchNewBool, upsertBool) in combination with collection.findAndModify(selector, updateModifier)