1

i am trying to update a document in mongo db with nodejs native driver.

initially it was inserted like:

matches {
    _id:2001,
    requester:"MITH",
    accepter:"NIKK",
    toss:"MITH",
    bat:"NIKK",
    scores:{"MITH":220},
    status:0,
    won:"MITH"
}

now i need to update the document where i need to insert a new element "NIKK":198 to scores object to make it scores:{"MITH":220,"NIKK":198}

problem is the key comes in a variable only. and when i update it is not updating

Below is the code with which i am trying

var _jsonMatch = {status:4};
var _scorepush = {}
_scorepush[variablevalue] = 198; // variablevalue in reference above is NIKK
var data = {"$set": _jsonMatch,"$push": {"scores":_scorepush} }
mith.findAndModify({_id:mith.db.bson_serializer.ObjectID.createFromHexString(matchId)},
        [],
        data,
        { upsert: true,new:true },
        function(error, match){ 
          if( error ) callback(error);
          else callback(null, match);
        });

EDIT :

I tried $addToSet instead of $push and i got the below error in callback with data undefined.

{ [MongoError: Cannot apply $addToSet modifier to non-array] name: 'MongoError', lastErrorObject: { err: 'Cannot apply $addToSet modifier to non-array', code: 12591, n: 0, connectionId: 56, ok: 1 }, errmsg: 'Cannot apply $addToSet modifier to non-array', ok: 0 } undefined

2 Answers 2

4

You need to build up your $set object programmatically to use dot notation in the key that sets 'scores.NIKK'. So to update the doc you've shown above:

variablevalue = 'NIKK';
var set = {
    status: 4
};
set['scores.' + variablevalue] = 198;
mith.findAndModify({_id: 2001},
    [],
    { $set: set },
    { upsert: true, new: true },
    function(error, match){
        if( error ) callback(error);
        else callback(null, match);
    }
);

Note: the awkwardness of this is because you're using dynamic keys that you need to build up at run-time. Consider re-working your schema so that scores is an array that looks something like this instead:

scores: [{name: 'MITH', value: 220}, {name: 'NIKK', value: 198}]
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! You just saved me from wasting 3 hours trying to undo the nesting structure of my app.
0

I think you want $set instead of $push:

var _jsonMatch = {status:4};
var _scorepush = {}
_scorepush[variablevalue] = 198; // variablevalue in reference above is NIKK
_jsonMatch["scores"] = _scorepush;
var data = {"$set": _jsonMatch };
mith.findAndModify({_id:mith.db.bson_serializer.ObjectID.createFromHexString(matchId)},
        [],
        data,
        { upsert: true,new:true },
        function(error, article){ 
          if( error ) callback(error);
          else callback(null, article);
        });

6 Comments

Thanks.. i will try with this and let you know.. :)
still its not updated .. i tried to access got as { "_id" : ObjectId("50f8ec6d527a262809000001"), "accepter" : "mithunsatheesh", "bat" : "mithunsatheesh", "requester" : "cricketfans", "scores" : { "mithunsathee sh" : 30 }, "status" : 3, "toss" : "mithunsatheesh", "won" : "-" }
Oops, I think it might just be $set not $addToSet
I tried this in beginning.. this overriden the initial value. resulting in only last insert in the json object scores.
Yea I don't think you can to it with an upsert, I believe you have to fetch the record, modify it, then save it.
|

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.