SCHEMA DESIGN
The most important factor in designing an application schema within MongoDB is matching the data access patterns of the application.
The main mongoDB schema design specifications :
- Rich documents
- Pre join / Embed data
- No mongo joins
- No constraints
- Atomic operations
- No declared Schema
It's important to keep data consistent even thought mongoDB lacks foreign keys constraints.
Embedding the fields within the same document ensures that the fields can be updated atomically. You should read the documentation about this.
One to One Relations
When you have two documents that are related to each other one-to-one, the two reasons to keep them in separate collection are :
- To reduce the working set size of your application.
- Because the combined size of the documents would be larger than 16MB.
Otherwise, you should embed one of them in the other according to these points :
- Frequence of access
- Size of items
- Atomicity of datas
One to Many Relations
You never should embed many inside one except if many is few like comments in a blog post.
So is it recommended to represent a one to many relationship in multiple collections whenever the many is large.
Of course, you can embed one in many if it is possible.
Many to Many Relations
You should separate the collections in this case, even though this relation is few to few. (example : books and authors documents). And embed only the id of the first inside the document of the second and vice-versa. This is the best way to make a relationship between them and avoid duplicate content.
Multikeys
The following query creates an index on the specified field if the index does not already exist :
db.collection.createIndex('teachers', 1)
Note that db.collection.ensureIndex() is deprecated since version 3.0.0. Use db.collection.createIndex() instead.
Benefits of Embedding
- Improved read performance
- One round trip to the database
Note that the one round trip is important. Indeed, speeding disk causes a high latency (1ms).
Trees
A good way to keep a good relationship tree is to define an ancestor property that containing the whole of the parents documents :
{
_id: 34,
name : "Snorkeling",
parent_id: 12,
ancestors: [12, 35, 90]
}
This following query will find all descendants of the "Snorkeling" category :
db.categories.find({ancestors:34})