3

I need to update some fields i am using mongoose driver and express js

schema:

 var mongoose = require('mongoose'),
    Schema = mongoose.Schema;

var ProfilesSchema = new Schema({

    presentRound: {
        type: Number,
        default: 1
    },

    scheduleInterviewStatus: {
        type: Boolean,
        default: false
    },

    interviewStatus: String,

    ratings: [{
        round: Number,
        rating: Number,
        feedback: String,
        interviewer: String,
        roundStatus: String
    }]
});

module.exports = mongoose.model('Profiles', ProfilesSchema);

so in these i need to update by id presentRound scheduleInterviewStatus interviewStatus and roundStatus(in ratings array by matching round number)

Before updating:

    presentRound: 1,
    scheduleInterviewStatus: true,
    interviewStatus: "on-hold",
    ratings: [{
        round: 1,
        rating: 3,
        feedback: "good communication skills",
        interviewer: "Vishal",
        roundStatus: "second opinion"
    }]

After Updating:

    presentRound: 2,
    scheduleInterviewStatus: false,
    interviewStatus: "in-process",
    ratings: [{
        round: 1,
        rating: 3,
        feedback: "good communicationskills",
        interviewer: "Vishal",
        roundStatus: "selected"
    }]

i have tried to run the query in robomongo first but getting error

Error: Fourth argument must be empty when specifying upsert and multi with an object.

Query:

   db.getCollection('profiles').update({
        "_id": ObjectId("57a9aa24e93864e02d91283c")
    }, {
        $set: {
            "presentRound": 2,
            "interviewStatus":"in process",
            "scheduleInterviewStatus": false          

        }
    },{
        "ratings.$.round": 1
    },{
        $set: {

            "ratings.roundStatus":"selected"


        }
    },
   { upsert: true },{multi:true})

I have no idea where i am going wrong

Please help.

swathi anupuram
  • 725
  • 1
  • 7
  • 14
  • multi and upsert can't be used together http://stackoverflow.com/questions/16322724/mongodb-update-with-upsert-and-multi-syntax – Amiram Korach Aug 10 '16 at 05:45
  • Why do you need several $set? Can you add a sample doc and what you expect it to be after the update? – Amiram Korach Aug 10 '16 at 05:45
  • I have updated my question @Amiram Korach – swathi anupuram Aug 10 '16 at 06:08
  • Sorry my mistake. You can combine multi and upsert but put them together `{upsert: true, multi: true}`. I think you need to combine the set to one object too. Look here: http://stackoverflow.com/questions/16322724/mongodb-update-with-upsert-and-multi-syntax – Amiram Korach Aug 10 '16 at 06:20

2 Answers2

5

Your update statement is incorrect, it has misplaced arguments - you are putting multiple $set operations and options as different parameters to the update method; they should be under separate designated update parameters. The correct Node.js syntax is:

update(selector, document, options, callback)

where selector is an object which is the selector/query for the update operation, document is also an object which is the update document and finally an optionsobject which by default is null and has the optional update settings.

Here you are doing

update(selector, document, selector, document, options, options, callback)

In which mongo is updating the collection using the first two parameters as correct and it naturally throws the error

Error: Fourth argument must be empty when specifying upsert and multi with an object.

because you have too many incorrect parameters specified.

Also, you have incorrect usage of the positional operator. It should be part of the document to be updated, not in the query.


For the correct implementation, follow this update

db.getCollection('profiles').update(
    /* selector  */
    {
        "_id": ObjectId("57a9aa24e93864e02d91283c"),
        "ratings.round": 1
    }, 
    /* update document */
    {
        "$set": {
            "presentRound": 2,
            "interviewStatus": "in process",
            "scheduleInterviewStatus": false,
            "ratings.$.roundStatus": "selected"    
        }
    },
    /* optional settings */
    { upsert: true, multi: true }
)
chridam
  • 88,008
  • 19
  • 188
  • 202
  • @swathianupuram No worries. Forgot to metion that since you are updating a single document, you don't need the `{ multi: true }` option here. – chridam Aug 10 '16 at 07:46
0

replace {upsert:true} -> {upsert:true,strict: false}

Pal
  • 787
  • 8
  • 20