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: 'john.smith@gmail.com',

    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:'john.smith@gmail.com'}, {$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

Community
  • 1
  • 1
cpeele00
  • 883
  • 4
  • 14
  • 29
  • 1
    Those aren't valid documents. You can't have unnamed nested objects like you're trying to do with `camps` and `instructors`. – JohnnyHK Jun 25 '13 at 03:05
  • 1
    did you mean `camps: {name:'cubs-killeen'}` instead of `camps:{ {name:'cubs-killeen'} }`? – Raj Nathani Jun 25 '13 at 03:06
  • @Relfor, yes that's what I meant! thanks for clarifying. Now, how to achieve that document structure? – cpeele00 Jun 25 '13 at 03:25
  • 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. – Paul Jun 25 '13 at 05:06
  • @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! – cpeele00 Jun 25 '13 at 05:31

2 Answers2

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" : "john.smith@gmail.com",
    "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: "john.smith@gmail.com" },
  {
    $push: {
      camps: { name: "cubs-killeen", location: "some other Place" }
    }
  }
);

Having this, you can add camps like this:

Hope it helps.

Emad Salah
  • 815
  • 1
  • 8
  • 19
AntonioOtero
  • 1,759
  • 1
  • 14
  • 16
  • 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 :-) – cpeele00 Jun 25 '13 at 17:56
  • 2
    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. – AntonioOtero Jun 25 '13 at 18:13
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' });
Keila
  • 1