kaxi1993
kaxi1993

Reputation: 4700

Insert into embedded document

I have the following schema:

var UserSchema = new Schema({
  username: { type: String, required: true },
  password: { type: String, required: true },
  userType: { type: String, default: 'user'},
  quizzHistory: [{
    quizzName: String,
    quizzScore: Number
  }]
});

my goal is to change document into embedded quizzHistory or insert new one if not exists document in embedded quizzeHistory

I try to set document into embedded quizzHistory :

User.findOneAndUpdate({ _id: req.session.user['_id'], 'quizzHistory.quizzName': testName},
{ 
    '$set': {
        'quizzHistory.$.quizzName': testName,
        'quizzHistory.$.quizzScore': finalScore
    }
}, {upsert: true},
function(err, upd) {
  console.log("added");
})

code above works if there is document in quizzHistory with required _id and quizzHistory.quizzName,but don't pushed new one if there isn't any document.

Is there any way in Mongodb to change document into embedded collection or insert new one if not exists ?

Upvotes: 1

Views: 569

Answers (3)

Lukasz Marek Sielski
Lukasz Marek Sielski

Reputation: 424

If you want to benefit for all possible plugins and methods added to model and don't want to fight with actual Mongo queries you should first retrieve user object, then push new element to quizzHistory array and do save. Something like below (you need to align that code to your needs).

var entry = {
  quizzName : 'abc',
  quizzScore : 123
};

User.findOne({_id:id, function(err, object) {
  if(err) {
    return someErrorCallback();
  }
  var 
  object.quizzHistory.push(entry);
  object.save(function(err) {
    if(err) {
      return someErrorCallback();
    }
    someSuccessCallback();
  });
});

Updating directly may be efficient, but questions usage of mongoose.

Hope it makes sense.

Upvotes: 1

Levan Gulisashvili
Levan Gulisashvili

Reputation: 101

this worked for me

User.update({ _id: req.session.user['_id'],'quizzHistory.quizzName':testName},
{ 
    $set: {
        "quizzHistory.$.quizzName":testName,
        "quizzHistory.$.quizzScore":finalScore
    }
},
function(err, upd) {
  if(!upd){
        User.update({ _id: req.session.user['_id']},
        { "$addToSet": { quizzHistory:  newScoreData }},function(err,data){
        });
  }
});

Upvotes: 1

pedrommuller
pedrommuller

Reputation: 16056

the reason is because you are using "find and update" you are not handling the condition when the row hasn't been found and create a new document, being said that you need manage the in a different way like

User.update({ _id: req.session.user['_id'], 'quizzHistory.quizzName': testName},
{ 
    '$push': {
        'quizzHistory.quizzName': testName,
        'quizzHistory.quizzScore': finalScore
    }
}, {upsert: true},
function(err, upd) {
  console.log("added");
})

Upvotes: 2

Related Questions