2

I'm trying to add an "Instructors" array into an already existing "Camps" array.

The hierarchical structure looks something like this:

owner = {

    email : '[email protected]',
    password : 'mypassword',
    firstName : 'john',
    lastName : 'smith',

    camps : [ 

                {

                    name : 'cubs-killeen',
                    location : 'killeen',
                    manager : {name: 'joe black', email: '', password: ''},

                    instructors : [

                        {

                            firstName : 'bill',
                            lastName : 'jones',

                            classes : []                        
                        }, 

                        {

                            firstName : 'jill',
                            lastName : 'jones',

                            classes : [],

                        },

                    ],

                    students : []

                }
            ]
};

I am using Node Express with MongoJS and have been able to successfully add an owner and add "camps", however, in the "addInstructor" function, when I try and add "Instructors" to a particular camp that is when the problems occur. I get no error message, instead it simply appends the "Instructors" array AFTER the items in the camps array.

Any help would be greatly appreciated. Below is my full code, with working functions and then the one that is not working and below that is my mongodb output (albeit wrong):

CampRepository = function(){};

CampRepository.prototype.addOwner = function(owner, callback){

    console.log(db);

    db.owners.save(owner, function(err, saved){
        if (err || !saved) {
            console.log('broke trying to add owner : ' + err);
            callback(err);
        } else {
            console.log('save was successful');
            callback(null, saved);
        }
    });
};


CampRepository.prototype.addCamp = function(ownerEmail, camp, callback){

    db.owners.update(
            {email: ownerEmail},
            {$push: {
                camps:{
                            name: camp.name,
                            location: camp.location,
                            managerName: camp.managerName,
                            managerEmail: camp.managerEmail,
                            managerPassword: camp.managerPassword,
                            managerPayRate: camp.managerPayRate,
                            instructors: [],
                            students: []
                        }
                    }
            }, function(err, saved){

                if (err || !saved) {
                    console.log('broke trying to add camp ' + err);
                    callback(err);
                } else {
                    console.log('save was successful');
                    callback(null, saved);
                }

    });

};


/*
    THIS IS THE ONE THAT DOESN'T WORK
*/
CampRepository.prototype.addInstructor = function(ownerEmail, campName, instructor, callback){

    db.owners.update(
            {email: ownerEmail, 'camps.name': campName},
            {$push: {
                        camps:{

                            instructors: {

                                firstName: instructor.firstName,
                                lastName: instructor.lastName,
                                email: instructor.email

                            },
                        }
                    }
            }, function(err, saved){

                if (err || !saved) {
                    console.log('broke trying to add camp ' + err);
                    callback(err);
                } else {
                    console.log('save was successful');
                    callback(null, saved);
                }

    });

};

OUTPUT

{ 
    "_id" : ObjectId("51c7b04d2746ef6078000001"), 
    "email" : "[email protected]", 
    "firstName" : john, 
    "lastName" : smith, 
    "password" : "mypassword", 
    "camps" : [  
                {   
                    "name" : "cubs-killeen",     
                    "location" : "killeen",     
                    "managerName" : "bill jones",     
                    "managerEmail" : "[email protected]",  
                    "managerPassword" : "secretpasscode",    
                    "instructors" : [ ],    
                    "students" : [ ] 
                },     
                {   "instructors" : {   "name" : "jon tisdale" } }
    ] 
}
2
  • 1
    you need to use the positional operator. update({...}, {$push:{"camps.$.instructors": etc} }) Commented Jun 24, 2013 at 2:57
  • Thanks for your feedback! I really appreciate it! I marked the other answer as correct for the sheer amount of effort he put into the answer, though technically you were both correct. Thanks again! :-) Commented Jun 24, 2013 at 16:54

1 Answer 1

3

You might need to take a look at this. you can achieve this using dot.notation It's very powerfull way to find or update items in a larger array of document scheme. If you still not able to achieve this i would happy to provide you the following code...

I've inserted a new owner2

owner2 = {

email : '[email protected]',
password : 'mypassword',
firstName : 'murali',
lastName : 'ramakrishnan',

camps : [ 

            {

                name : 'Rotary club',
                location : 'trichy',
                manager : {name: 'baskaran', email: '[email protected]', password: 'baskaran'},

                instructors : [

                    {

                        firstName : 'baskaran',
                        lastName : 'subbiah',

                        classes : []                        
                    }, 

                    {

                        firstName : 'david',
                        lastName : 'nover',

                        classes : [],

                    },

                ],

                students : []

            }
        ]};

If you see we just need to add a new instructor as requested... let first add the document to the collection

db.try.insert(owner2);

here you go you have added a new document now, i'm going to create a new instructor object to insert @newly created owner2

instructor1 = {
          firstName : 'lakshmi',    
          lastName : 'kanthan',
          classes : []
        };

above is the document object for new instructor you can perform this update in many ways, using mongodbs methods like

collection.update collection.findAndModify

if you want to insert or update any value to the sub-document we need to find using a dot.notation and push the sub-document to the document, here the code

db.try.update(
     {'camps.name': "Rotary club" },
     {
        $push: { 'camps.$.instructors' : instructor1 }
     }
)

the above code inserts a new record under the instructor field as in the field an array it just pushes the sub-document

End-Result

{
"_id" : ObjectId("51c7b222c0468dc711a60916"), 
"email" : "[email protected]",
"password" : "mypassword",
"firstName" : "murali",
"lastName" : "ramakrishnan",

"camps" : [ 

            {

                "name" : "Rotary club",
                "location" : "trichy",
                "manager" : {"name": "baskaran", "email": "[email protected]", "password": "baskaran"},

                "instructors" : [

                    {

                        "firstName" : "baskaran",
                        "lastName" : "subbiah",

                        "classes" : []                        
                    }, 

                    {

                        "firstName" : "david",
                        "lastName" : "nover",

                        "classes" : [],

                    },
        {

                        "firstName" : "lakshmi",
                        "lastName" : "kanthan",

                        "classes" : [],

                    }

                ],

                "students" : []

            }
        ]};
Sign up to request clarification or add additional context in comments.

4 Comments

It worked!! Thanks very much for all the time you took to explain it! I really appreciate it!
So I am trying to apply this same logic to add an item to the classes array, but it's not working. Any ideas? db.owners.update( { email:"[email protected]", 'camps.name':"cubs-killeen", 'instructors.lastName':"tisdale" }, { $push: {'camps.$.instructors.$.classes': {type: "painting"}} } )
you can only have one positional operator: jira.mongodb.org/browse/SERVER-831
Thanks Asya, that helped out! :-)

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.