Doug
Doug

Reputation: 23

Mongoose FindOneandUpdate - Only update Specific fields leave others alone

Maybe I'm not wording this properly but hopefully I can find some help with this. I've been playing around with mongoose schema's and boy its doing my head in with this issue..

I want to update a document on a collection under a specific ID, I've got all that working however. I'm running into an issue where since I never supplied values for others I dont want updated it makes them either all Null or deletes them if omitUndefined is turned on.

router.put('/api/playerinfo/:player_steamID/main_server', passport.authenticate('basic', {session: false}),
function(req, res){
  const params = {
    main_server: {
          game_stats:{
             kills: req.body.main_server.game_stats.kills,
             deaths: req.body.main_server.game_stats.deaths,
          }
    }
  };

PlayerInfo.findOneAndUpdate({player_steamID: req.body.player_steamID }, {$set: params}, { upsert: true, new: true }).then(playerinfo =>{
res.json(playerinfo)
});
});

For example: Current Stored information

{
"name": "Jimbo",
"steamID": "123456",
"main_server": {
    "game_stats": {
        "kills": 3,
        "deaths":0
    }
}
}

Then if we used the above code to modify the fields.. But we did not supply a death value for that field, it would null out the bottom or remove it entirely if omit is true.

Sending postman update with the following:

{
"name": "Jimbo",
"steamID": "123456",
"main_server": {
    "game_stats": {
        "kills": 34
    }
}
}

Updated Information

{
"name": "Jimbo",
"steamID": "123456",
"main_server": {
    "game_stats": {
        "kills": 34,
        "deaths": null
    }
}
}

What I would like to know is the best way to modify multiple fields without it "changing" the last value. if a field is missing. Is that possible?

IE: If i only supply kills value and leave json update for deaths blank it would retain the old value from deaths.

Thanks.

-- Fixed. created a object inside $set then to update old values without replacing you need to wrap them in quotes. 'main_server.game_stats.kills' : req.body.....kills etc.

Upvotes: 1

Views: 7718

Answers (4)

Tejas Shirnalkar
Tejas Shirnalkar

Reputation: 153

What I did was retrieve the original value in hidden input field using Ejs something like:

<input type="hidden" name="nameOf_thefield" value="<%= variable %>" />

Pass the value req.body.nameOf_thefield to the variable which you wish not to change

Upvotes: 0

Naosirium Kinesso
Naosirium Kinesso

Reputation: 31

You can try just put part of model, which contains specific field for update

  _userModelRepository.updateUser( { email: req.user.email }, { specificField: specificValue});

Here's schema implementation

   updateUser = function(query, params){
    return _userModelRepository.findOneAndUpdate(query, params, function(err, result) {
                if (err) {
                    throw err;
                }
            });
    }

Upvotes: 0

Doug
Doug

Reputation: 23

Fixed. created a object inside $set then to update old values without replacing you need to wrap them in quotes. 'main_server.game_stats.kills' : req.body.....kills etc.

I also did a for loop in the object and assigned props to handle multiple values or single if passed through from json.

Upvotes: 1

Thalaivar
Thalaivar

Reputation: 23632

Use $set to update only certain fields.

PlayerInfo.findOneAndUpdate({steamID: req.body.steamID },{ $set: {'yourcoll.$.someField': 'Value'} }, { upsert: true, new: true }).then(playerinfo =>{
     res.json(playerinfo)
});

Documentation:

https://docs.mongodb.com/manual/reference/operator/update/set/

Upvotes: 2

Related Questions