MongoDb : How to insert additional object into object collection?
Asked Answered
F

2

19

I have a document "owner" that can have "n" number of camps and camps have "instructors" and instructors have "classes". Earlier I tried accomplishing this with nested arrays (see link to my post below), however I learned that the positional operator "$" does not nest that deep. MongoDB: Adding an array into an existing array

However, I learned that the workaround would be to use object collections instead of arrays. I'm assuming that I have to use "update" with "$set" to add additional "camps", however every time I do all it does is overwrite(update) the previous camp that was inserted.

Below is the hierarchical structure I am trying to accomplish:

owner = {

    firstName: 'john',
    lastName: 'smith',
    ownerEmail: '[email protected]',

    camps : {

        {
            name: 'cubs-killeen',
            location: 'killeen'
        },

        {
            name: 'cubs-temple',
            location: 'temple'
        },

        instructors : {

            {
                firstName: 'joe',
                lastName : 'black'
            },

            {
                firstName: 'will',
                lastName : 'smith'
            }        
        }

    }

}

I have also been trying the following:

db.owners.update({ownerEmail:'[email protected]'}, {$set: { camps:{ {name:'cubs-killeen'} } }})

but this throws an unexpected identifier { error.

Any help with some sample mongo commands to achieve the structure above would be most appreciated.

V/R

Chris

Fabrianne answered 25/6, 2013 at 2:58 Comment(5)
Those aren't valid documents. You can't have unnamed nested objects like you're trying to do with camps and instructors.Payload
did you mean camps: {name:'cubs-killeen'} instead of camps:{ {name:'cubs-killeen'} }?Phyllida
@Relfor, yes that's what I meant! thanks for clarifying. Now, how to achieve that document structure?Fabrianne
MongoDB is more or less a javascript object store. In Javascript, Lists, such as a list of instructors, use [] brackets not {} curly ones. Curly {} brackets contain objects that store key: value pairs. Also I think classes should be another property of the camp not an instructor. You could have schedule, location and instructor be properties of classes.Cynosure
@Paul, thanks for replying! What I'm really looking for is what Mongodb command syntax do I have to use to achieve this...or how would I do this with MongoJS, either or. Thanks again!Fabrianne
I
26

As other mentioned, The structure you want is not valid. I recommend the following structure for your owner document:

    {
    "_id" : ObjectId("51c9cf2b206dfb73d666ae07"),
    "firstName" : "john",
    "lastName" : "smith",
    "ownerEmail" : "[email protected]",
    "camps" : [
            {
                    "name" : "cubs-killeen",
                    "location" : "killeen"
            },
            {
                    "name" : "cubs-temple",
                    "location" : "temple"
            }
    ],
    "instructors" : [
            {
                    "firstName" : "joe",
                    "lastName" : "black"
            },
            {
                    "firstName" : "will",
                    "lastName" : "smith"
            }
    ]
}

and then

db.stack.update(
  { ownerEmail: "[email protected]" },
  {
    $push: {
      camps: { name: "cubs-killeen", location: "some other Place" }
    }
  }
);

Having this, you can add camps like this:

Hope it helps.

Illinois answered 25/6, 2013 at 17:19 Comment(2)
hmmm, how then would I associate an instructor with a camp? And then classes with the Instructor(since different instructors teach different classes)? This approach seems to take a way from the Rich Document benefits of Mongo. Maybe I should just use Mongoose and design this in a relational way. Thanks for the reply :-)Fabrianne
So, a camp can have several instructors? In that case, just put the "instructors" list inside each camp in "camps". You can make it an array of strings for simplicity like this: "instructors":["Joe Black","Will Smith","Some Other"]. If you want to store more info about the instructors just create a new collection "instructors" and have the name be the ID. {"_id":"Joe Black", "age":21, "phone":"123"}. Try thinking on simplicity and how your data will be queried before considering thinking on Relational. NoSQL (NoRelational) is hard to catch in your mind but it pays back when you do.Illinois
S
0
var newObject = {usuario: req.body.usuario, fecha: req.body.fecha, edit: 
req.body.edit};

await Documentos.findByIdAndUpdate(id,
 { deleted_doc: true,
 $push: { history: newObject } }); 
res.json({ status: 'Documentos Updated' });
Shark answered 4/11, 2020 at 17:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.