1

I'm saving data for a NestJs based web app in MongoDB.

My MongoDB Data looks like this

"gameId": "1a2b3c4d5e"
"rounds": [
    {
      "matches": [
        {
          "match_id": "1111abc1111",
          "team1": {
            "team_id": "team8",
            "score": 0
          },
          "team2": {
            "team_id": "team2",
            "score": 0
          }
        },
        {
          "match_id": "2222abc2222",
          "team1": {
            "team_id": "team6",
            "score": 0
          },
          "team2": {
            "team_id": "team5",
            "score": 0
          }
        },
      ]
    }
  ]

Here we have gameId for each game and inside each game, there are many rounds and many matches. Each match has match_id. How can I get a particular match info and edit it based on gameId & match_id? (N.B: I'm willing to update score based on match_id)

I've tried something like this

    const matchDetails = await this.gameModel.findOne({
      gameId: gameId,
      rounds: { $elemMatch: { match_id: match_id } },
    });

But this doesn't work and returns null. How to do this correctly?

Meraj Kazi
  • 65
  • 10

1 Answers1

1

The problem is that you're applying the elemMatch on the rounds array, but it should be on rounds.matches. Changing your query to the following will fix the problem:

const matchDetails = await this.gameModel.findOne({
      gameId: gameId,
      "rounds.matches": { $elemMatch: { match_id: match_id } },
});

EDIT: To only get a specific matching element, you can use a simple aggregation with $unwind and $filter:

db.collection.aggregate([
  {
    "$match": {
      "gameId": gameId,
      "rounds.matches": { $elemMatch: { match_id: match_id } }
    }
  },
  {
    "$unwind": "$rounds"
  },
  {
    $project: {
      match: {
        $filter: {
          input: "$rounds.matches",
          as: "match",
          cond: {
            $eq: [
              "$$match.match_id",
              match_id 
            ]
          }
        }
      },
      _id: 0
    }
  }
])

Example on mongoplayground.

eol
  • 23,236
  • 5
  • 46
  • 64
  • Doesn't work as expected. Returns all the matches. Not the one with particular match_id – Meraj Kazi Nov 29 '21 at 10:58
  • Wait, you mean you want to only get the matching array element? – eol Nov 29 '21 at 11:17
  • yes. I want only the particular match that matches with the match_id – Meraj Kazi Nov 29 '21 at 11:28
  • Oh ok, see my update. – eol Nov 29 '21 at 11:44
  • This works. Though it became a bit complex than I expected. But does the work. Any Idea how can I update scores inside the teams? – Meraj Kazi Nov 29 '21 at 11:57
  • You could use `arrayfilters` as described here (https://stackoverflow.com/a/70020370/3761628). You may want to ask a separate question regarding the update, if you need further help. Please consider upvoting/accepting this one, thanks :) – eol Nov 29 '21 at 12:09