1

I am working on moving my database from sqlite3 to mongo. I went through mongo university, yet I'm not sure I have found a really good example of upsertting in bulk.

Use case : user uploads a data file with a list of players and their stats. The app needs to either update a player or add a new player if they do not already exist.

Current Implementation : Function takes a list of Players and creates SQL statement.

let template = '(Player.Rank, Player.Player_ID, Player.Player, Player.Score, TTP, 1),(Player.Rank, Player_ID, ...) ... (... TTP, 1)';

const stmt = `INSERT INTO playerStats (Rank, Player_ID, Player, Score, TPP, Games_Played) 
VALUES ${template}
ON CONFLICT(Player_ID) DO UPDATE 
SET Score = Score+excluded.Score, TPP=TPP+excluded.TPP, Games_Played=Games_Played+1`;

db.run(stmt, callback);

Im hoping to have each document be a league which contains players, games, and managers. Mongo DB document template

{
    "LEAGUE_ID": "GEO_SAM",
      "Players": [
        {
          "id": "PlayerID",
          "name": "Player",
          "score": "Score",
          "rank": "Rank",
          "xPlayed": "Games_Played",
          "ttp": "TTP"
        }
      ],
      "Managers": [
        {...}
      ],
      "Games": [
        {...}
      ]
  }

I am totally lost and not sure how to get this done. Do I need to create a loop and ask mongo to upsert on each iteration? I have searched through countless examples but all of them use static hard coded values.

Here is my testing example.

const query = { League_id : "GEO_SAM", Players.$.id: $in{ $Players }};
const update = { $inc: { score: $Player.Score}};
const options = { upsert: true };
collection.updateMany(query, update, options);

I also don't understand how to pass the entire player object to push to the array if the player_id isn't found.

1 Answer 1

1

My solution was to create a metaData field containing the league ID with a single player. If anyone else has a better solution I would love to hear from you.

   {
      MetaData: { "LEAGUE_ID": "GEO_SAM"},
      Player: {
        "id": "PlayerID",
        "name": "Player",
        "score": "Score",
        "rank": "Rank",
        "xPlayed": "Games_Played",
        "ttp": "TTP"
        }
  }

Then I mapped over the values and inserted each one.

client.connect().then((client) => {
        const db = client.db(dbName);
        const results = Players.map((player) => {
          db.collection('Players').updateOne(
            { Player_Name: player.Player_ID },
            {
              $setOnInsert: {
                Player_ID: player.Player_ID,
                Player: player.Player,
                Rank: player.Rank,
              },
              $inc: { Score: player.Score, Games_Played: 1, TPP: player.TPP },
            },
            { upsert: true, multi: true },
          );
        });
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.