buydadip
buydadip

Reputation: 9407

Mongoose - How to update object in array and then sort the updated array?

I have the following document...

{
"_id": {
  "$oid": "5bca528b49079d64dd4cea5d"
},
"song_queue": [
  {
     "song_id": "best",
     "vote": 1
  },
  {
    "song_id": "west",
    "vote": 1
  }
],
"room_id": "FHWAN",
"__v": 0

My issue is that I need to first update a vote for one of the songs and then re-arrange the order of the array based on the vote count.

I have a way of doing it with two separate queries...

// Give the song an upvote.
await Room.findOneAndUpdate(
  { "song_queue.song_id": song.song_id },
  {$set: { "song_queue.$.vote": song.votes }},
  { new: true }
);

// Sort the queue.
room = await Room.findOneAndUpdate(
  { room_id: data.room_id },
  { $push: { song_queue: { $each: [], $sort: { vote: -1 } } } },
  { new: true }
);

Is there a way to merge the two queries into one query, or perhaps make it more concise? I would like one query that updates the song in song_queue and then sorts the array after the change.

Upvotes: 0

Views: 982

Answers (1)

Volodymyr
Volodymyr

Reputation: 1408

There is no way to merge this queries because the order of the operations inside update parameter is not guaranteed to be preserved so the code like this might fail to run correctly because you can't be sure that updating song_queue.$.vote with occur before song_queue is sorted:

await Room.findOneAndUpdate(
  { "song_queue.song_id": song.song_id },
  {
    $set: { "song_queue.$.vote": song.votes },
    $push: { song_queue: { $each: [], $sort: { vote: -1 } } }
  },
  { new: true }
);

What can be done to optimize db querying is using Ordered Bulk Write operation which will make only one round trip to MongoDB instead of two.

Upvotes: 1

Related Questions