Raim Khalil
Raim Khalil

Reputation: 387

Find One and Update with random document?

I want to find and update one random document that meets the specified criteria. I looked at the aggregate $sample keyword but I'm not sure how to combine it with a regular findOneAndUpdate. The current code is:

           const opts = { session };
           const savingGoal = await Goal.findOneAndUpdate({'participants.userID': {$ne : socket.uid},  private : {$ne : true}, goalType : category, $expr: { /** Allows the use of aggregation expressions within the query language  */
                $lte: [
                  {
                    $size: "$participants"
                  },
                  12
                ]
              }}, 
              {$push: {participants: participant}}, 
              {new : true, session})

Ideally, I'd like to just find any random document and update that by adding a new participant. Any suggestions?

Upvotes: 1

Views: 512

Answers (1)

turivishal
turivishal

Reputation: 36114

I don't think any straight option available to update random document, but you can do 2 queries, the first aggregation query to select a single document using $sample stage, and then the update query.

const opts = { session };
// AGGREGATION TO SELECT SINGLE RANDOM DOCUMENT
const savingGoal = await Goal.aggregate([
  {
    $match: {
      'participants.userID': { $ne : socket.uid },  
      private: { $ne : true }, 
      goalType: category, 
      $expr: {
        $lte: [{ $size: "$participants" }, 12]
      }
    }
  },
  { $sample: { size: 1 } }
]);

// UPDATE QUERY
if (savingGoal.length) {
  await Goal.updateOne(
    { _id: savingGoal[0]._id }, 
    { $push: { participants: participant } }, 
    { session } 
  ); 
}

Upvotes: 2

Related Questions