2

I am new to MongoDB and MongooseJS. I am also quite inept at creating databases, sorry.

First question

what is the difference between sub docs and population? Looking at the docs example, a Parent-Children subdoc seems very similar to a Person-Stories population.

Database schema question

Scenario: users can create a number of Canvas. Each Canvas can host a number of Shapes. Each Shape can be of 2 types: Simple, or Complex. A Simple shape can be a Square or a Circle (objects). A Complex shape is made of a Frame and a Material.

            Canvas
               |
             Shape
            /     \       
      Simple       Complex: Frame, Material 
      /     \
Square       Circle

Now, a Shape can be assigned to only 1 Canvas but can be moved between Canvases or live alone outside a Canvas. Frame and Material can be created independently (live alone) and added to a Complex Shape (each Complex Shape can only have 1 frame and 1 material).

Some of the queries I would have to implement are asking for all the shapes in a specific Canvas, or all the shapes that are using a certain material, or again all the Frames that are being used by shapes.

Since the difference between sub-doc and population is not clear to me, I am not even sure how to begin... any help or example would be appreciated (I am not expecting a full and working database schema).

fusio
  • 3,595
  • 6
  • 33
  • 47
  • What does the data structure look like for things like Shape, Simple and Complex? – Alistair Nelson Aug 12 '13 at 09:46
  • Uhm, I guess `Simple` is not really required. I am coming from a Java background, hence I would create a `Shape` class with id, position, size, .. and then both the Simple shapes (`Square`, `Circle`, ..) and `ComplexShape` would inherit from it. The simple shapes will have different attributes, while the `ComplexShape` would have a `Frame` and a `Material` -- maybe in JS there are better ways than using [Classical Inheritance](http://javascript.crockford.com/inheritance.html) to do something similar? – fusio Aug 12 '13 at 11:01

1 Answers1

1

In answer to part one, the difference is that in a Document-Subdocument scenario the subdocument is stored with the document (as a child document, accessible through the use of dot notation).

In the Mongoose populate scenario, a reference is held to a document in another collection. When you tell mongoose to populate what it does is make another query to MongoDB to get this 'subdocument'.

The main difference I see is that with the mongoose populate method you cannot query for documents using the 'subdocument' properties, whereas you can with the embedded subdocument model.


Edit, subdocument example

So in MongoDB you can store the data as nested subdocuments like so:

{
    _id: acbdbd,
    "property": "value",
    "subdocumentproperty" : {
        "param1": 1,
        "param2": 2
    }
}

This data is only stored with the master document and your querying would be done through the master document, e.g.

db.collection.find({"subdocumentproperty.param1": 1})
Alistair Nelson
  • 3,115
  • 1
  • 16
  • 15
  • So sub-documents cannot live on their own.. e.g. can I create a sub-document and not assign it to any Document? In the example: if a ComplexShape has a Frame sub-document, can I separate the Frame from the Shape and still have it stored into the DB for later use? – fusio Aug 12 '13 at 09:38
  • You can do that, it all depends on how you are going to query your data as to how you structure your documents. – Alistair Nelson Aug 12 '13 at 09:40
  • The question is: a sub-docs can be used as doc? It seems it does not have a Model, so can you for instance query for all the sub-docs of a certain type that are in the database? – fusio Aug 12 '13 at 12:10
  • No, a sub document only exists on the parent document. They are really just a collection of properties on the parent. I will add an example of what I think you mean to the answer. – Alistair Nelson Aug 12 '13 at 12:59
  • Oh I see.. so a sub-document is very much like a json object which is member of another json object. `doc = { key1:val, sub-doc: { key2:val, .. } }`. While a population is used when instead of the sub-doc, I am storying the objectid that will be used for the join. Something like this? – fusio Aug 12 '13 at 13:17
  • Think of the population as being akin to a SQL join, but without the ability to query on the joined documents properties. – Alistair Nelson Aug 12 '13 at 13:58
  • Not sure how long this feature has been around, but mongoose currently DOES SUPPORT adding query conditions to population. See the "query conditions and other options" section of this guide http://mongoosejs.com/docs/populate.html – Ben Fischer Jun 06 '14 at 19:27