3

I have some documents with below format

{
    "count_used" : Int64,
    "last_used"  : Date,
    "enabled"    : Boolean,
    "data"       : String
}

I use the last_used field to sort on within an aggregate query so the last used document is served first. I use updateOne after the aggregate to bump the last used field using the below query. So every read request will change the last_used field date stamp.

updateOne(
    { _id: result['_id']}, 
    {
        $currentDate: { 'last_used': true }, 
        $inc: { 'count_used': 1 }
    }
)

The problem i have is clients will make 5 concurrent requests and instead of receiving document 1,2,3,4,5 they will get 1,1,1,2,2 for example.

I'm guessing this is because there is no lock between the read and the update, so several reads get same results before the update is performed.

Is there any way around this?

Update with below aggregate nodejs code

db.collection('testing').aggregate([{
    $project: {
    last_used  : 1,
    count_used : 1,
    doc_type   : 1,
    _id        : 1,
    data       : 1,
    is_type    : { $setIsSubset: [ [type], '$doc_type' ] }
    }
},
{ $match: {
    $or: query} 
},
{ $sort: { 
    is_type: -1, 
    last_used: 1 
    } 
},
{ 
  $limit: 1 
} ]).next(function (error, result) {  

    db.collection('adverts').updateOne({_id: result['_id']}, {$currentDate: {'last_used': true}, $inc: {'count_used': 1}})        

}

The problem is that multiple read requests come in from same client who issues multiple concurrent requests, which means they hit db at the same time and read the same data before the updateOne fires.

Flo Woo
  • 949
  • 1
  • 12
  • 26
  • Can you add your aggregation query? I wonder what that looks like. – Amin J Sep 26 '16 at 16:30
  • have you found a way to solve this? I am having a similar problem https://stackoverflow.com/questions/48921005/mongodb-use-findandmodify-on-specific-document-among-multiple-match – forJ Feb 22 '18 at 07:00
  • An idea would be to use $merge as the last stage of your aggregation pipeline to avoid having 2 separate queries, but i'm not sure it that would be atomic: https://docs.mongodb.com/manual/reference/operator/aggregation/merge/ – Maikel Ruiz Jan 18 '21 at 13:42

0 Answers0