Gabriel Lupu
Gabriel Lupu

Reputation: 1447

Add new element to mongoDB document array only if a certain condition is met

I have this mongoDB document structure:

Game = {
  _id: 'randomObjectId',
  players: [Array of players ObjectIds],
  maxPlayers: 2,
  status: 'created' (or 'fully-booked')
}

When a new player joins the game I want to add him to the players array and change the status of the game to fully-booked only if this condition is met: players.length < maxPlayers.

To recap:

Without this check it's easy to make the query using:

Game.findByIdAndUpdate('randomObjectId', {
  $addToSet: {
    players: 'playerObjId'
  },
  gameStatus: 'fully-booked'
}, {
  new: true
})

What I don't know is how to add this condition to this (or other type of) query. Any help is appreciated. Thanks

Upvotes: 1

Views: 375

Answers (1)

Dĵ ΝιΓΞΗΛψΚ
Dĵ ΝιΓΞΗΛψΚ

Reputation: 5669

you can try an aggregation pipeline update like the following. however, if already fully booked, the command will return a null. also note that if you try to add a player id that already exists in the array, it won't be added.

db.collection.findOneAndUpdate(
    {
        _id: someObjectId,
        $expr: {
            $lt: [{ $size: "$players" }, "$maxPlayers"]
        }
    },
    [
        {
            $set: {
                players: { $setUnion: ["$players", [newPlayerObjectId]] }
            }
        },
        {
            $set: {
                status: {
                    $cond: {
                        if: { $lt: [{ $size: "$players" }, "$maxPlayers"] },
                        then: "created",
                        else: "fully-booked"
                    }
                }
            }
        }
    ],
    {
        returnNewDocument: true
    })

Upvotes: 1

Related Questions