MongoDB: Adding an array into an existing array
Asked Answered
A

1

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" } }
    ] 
}
Allomorph answered 24/6, 2013 at 2:23 Comment(2)
you need to use the positional operator. update({...}, {$push:{"camps.$.instructors": etc} })Katekatee
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! :-)Allomorph
S
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" : []

            }
        ]};
Shivaree answered 24/6, 2013 at 4:15 Comment(4)
It worked!! Thanks very much for all the time you took to explain it! I really appreciate it!Allomorph
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"}} } )Allomorph
you can only have one positional operator: jira.mongodb.org/browse/SERVER-831Katekatee
Thanks Asya, that helped out! :-)Allomorph

© 2022 - 2024 — McMap. All rights reserved.