Implementing Schema Design Patterns
1. Using Attribute Pattern
| Aspect | Detail |
|---|---|
| Use when | Many similar fields with sparse values |
| Form | Array of {k, v} pairs |
| Index | {"attrs.k": 1, "attrs.v": 1} |
{ _id, attrs: [ {k: "color", v: "red"}, {k: "size", v: "M"} ] }
2. Using Bucket Pattern
| Aspect | Detail |
|---|---|
| Use when | Time-series / IoT data |
| Form | One doc per (entity, time-bucket) with array of measurements |
| Benefit | Fewer docs, better compression |
| Modern alternative | Time Series Collections (built-in) |
3. Using Computed Pattern
| Aspect | Detail |
|---|---|
| Use when | Expensive aggregations done frequently |
| Form | Store pre-computed values (totals, counts) |
| Maintenance | Update on write or via change streams |
4. Using Document Versioning Pattern
| Aspect | Detail |
|---|---|
| Use when | Audit trail / time travel needed |
| Form | Current doc + history collection of prior versions |
| Triggers | Change streams write to history |
5. Using Extended Reference Pattern
| Aspect | Detail |
|---|---|
| Use when | Reference + frequently-accessed fields |
| Form | Store ref id + duplicated hot fields (name, avatar) |
| Drawback | Must update on source change |
6. Using Outlier Pattern
| Aspect | Detail |
|---|---|
| Use when | Most docs are small, a few huge |
| Form | Flag outliers; overflow into linked collection |
| Benefit | Keeps common path fast |
7. Using Polymorphic Pattern
| Aspect | Detail |
|---|---|
| Use when | Similar but varied entities (vehicles: car/bike/truck) |
| Form | Single collection, type field, varied fields per type |
| Indexes | On type + common queryable fields |
8. Using Subset Pattern
| Aspect | Detail |
|---|---|
| Use when | Embedded array too large; only top-N needed for typical reads |
| Form | Top-N embedded + full set in separate collection |
9. Using Tree Patterns
| Pattern | Best For |
|---|---|
| Parent reference | Simple insert, no descendants query without $graphLookup |
| Child references | Easy descendants, hard insert |
| Array of ancestors | Easy ancestor & descendants |
| Materialized path | Path string ("/a/b/c"); fast prefix queries |
| Nested sets | Read-heavy, rare changes |
10. Using Schema Versioning Pattern
| Aspect | Detail |
|---|---|
| Form | Add schema_version field |
| Migration | Lazy upgrade on read OR batch update |
| Code | Handle multiple versions in app layer |