SlideShare a Scribd company logo
Schema Design
       
Roger Bodamer
 roger@analytica.com
      @rogerb
A brief history of Data Modeling
•  ISAM	

  • COBOL 	

•  Network 	

•  Hiearchical	

•  Relational	

  • 1970 E.F.Codd introduces 1st Normal Form (1NF)	

  • 1971 E.F.Codd introduces 2nd and 3rd Normal Form (2NF, 3NF	

  • 1974 Codd  Boyce define Boyce/Codd Normal Form (BCNF)	

  • 2002 Date, Darween, Lorentzos define 6th Normal Form (6NF)	

• Object
So why model data?
Modeling goals
Goals:	

•  Avoid anomalies when inserting, updating or deleting	

•  Minimize redesign when extending the schema	

•  Make the model informative to users	

•  Avoid bias towards a particular style of query	





                                                       * source : wikipedia
Relational made normalized
data look like this
Document databases make
normalized data look like this
Some terms before we proceed
RDBMS	

           Document DBs	

Table	

           Collection	

View / Row(s)	

   JSON Document	

Index	

           Index	

Join	

            Embedding  Linking across
                   documents	

Partition	

       Shard	

Partition Key	

   Shard Key
Recap

Design documents that simply map to
your application

post	
  =	
  {author:	
   roger ,	
  
	
  	
  	
  	
  	
  	
  	
  	
  date:	
  new	
  Date(),	
  
	
  	
  	
  	
  	
  	
  	
  	
  text:	
   Down	
  Under... ,	
  
	
  	
  	
  	
  	
  	
  	
  	
  tags:	
  [ rockstar , men	
  at	
  work ]}
Query operators

Conditional operators:
       $ne, $in, $nin, $mod, $all, $size, $exists, $type, ..
       $lt, $lte, $gt, $gte, $ne, 

        // find posts with any tags
        db.posts.find({tags: {$exists: true}})


	
  
Query operators

Conditional operators:
       $ne, $in, $nin, $mod, $all, $size, $exists, $type, ..
       $lt, $lte, $gt, $gte, $ne, 

        // find posts with any tags
        db.posts.find({tags: {$exists: true}})

Regular expressions:
         // posts where author starts with k
         db.posts.find({author: /^r*/i }) 

	
  
Query operators

Conditional operators:
       $ne, $in, $nin, $mod, $all, $size, $exists, $type, ..
       $lt, $lte, $gt, $gte, $ne, 

        // find posts with any tags
        db.posts.find({tags: {$exists: true}})

Regular expressions:
         // posts where author starts with k
         db.posts.find({author: /^r*/i }) 

Counting: 
          // posts written by mike
	
  	
  db.posts.find({author:	
   roger }).count()	
  
Extending the Schema

    
        new_comment = {author: Bruce , 
                  date: new Date(),
                  text: Love Men at Work!!!! }

        new_info = { $push : {comments: new_comment},
                   $inc : {comments_count: 1}}

	
  db.posts.update({_id:	
   ... 	
  },	
  new_info)	
  
Extending the Schema

    
        { _id : ObjectId(4c4ba5c0672c685e5e8aabf3), 
          author : ”roger,
          date : Sat Jul 24 2010 19:47:11 GMT-0700 (PDT), 
          text : ”Down	
  Under...,
          tags : [ ”rockstar, ”men at work ],
          comments_count: 1, 
          comments : [
            
{
            
    
author : ”Bruce,
            
    
date : Sat Jul 24 2010 20:51:03 GMT-0700 (PDT),
            
    
text : ” Love Men at Work!!!!
            
}
          ]}
Extending the Schema

        // create index on nested documents:
        db.posts.ensureIndex({comments.author: 1})

        db.posts.find({comments.author:”Bruce”})

        // find last 5 posts:
        db.posts.find().sort({date:-1}).limit(5)

        // most commented post:
         db.posts.find().sort({comments_count:-1}).limit(1)

        When sorting, check if you need an index
Intro to MongoDB and datamodeling
Modeling Patterns

Single table inheritance

One to Many

Many to Many

Trees

Queues
Single Table Inheritance


    db.shapes.find()
     { _id: ObjectId(...), type: circle, area: 3.14, radius: 1}
     { _id: ObjectId(...), type: square, area: 4, d: 2}
     { _id: ObjectId(...), type: rect, area: 10, length: 5, width: 2}

    // find shapes where radius  0 
    db.shapes.find({radius: {$gt: 0}})

    // create index
    db.shapes.ensureIndex({radius: 1})
One to Many

- Embedded Array / Using Array Keys
    - slice operator to return subset of array
    - hard to find latest comments across all documents
One to Many

- Embedded Array / Array Keys
      - slice operator to return subset of array
      - hard to find latest comments across all documents

- Embedded tree
      - Single document
      - Natural
One to Many

- Embedded Array / Array Keys
      - slice operator to return subset of array
      - hard to find latest comments across all documents

- Embedded tree
      - Single document
      - Natural 
    
- Normalized (2 collections)
      - most flexible
      - more queries
Many - Many

Example:
  
- Product can be in many categories
- Category can have many products

  Products	

                      Category	

  - product_id	

                  - category_id	


            Prod_Categories	

            -  id	

            -  product_id	

            -  category_id
Many – Many
products:
 { _id: ObjectId(4c4ca23933fb5941681b912e),
   name: Sumatra Dark Roast,
   category_ids: [ ObjectId(4c4ca25433fb5941681b912f),
                   ObjectId(4c4ca25433fb5941681b92af”]}
Many – Many 
products:
    { _id: ObjectId(4c4ca23933fb5941681b912e),
      name: Sumatra Dark Roast,
      category_ids: [ ObjectId(4c4ca25433fb5941681b912f),
                      ObjectId(4c4ca25433fb5941681b92af”]}
    
categories:
    { _id: ObjectId(4c4ca25433fb5941681b912f), 
      name: Indonesia, 
      product_ids: [ ObjectId(4c4ca23933fb5941681b912e),
                     ObjectId(4c4ca30433fb5941681b9130),
                     ObjectId(4c4ca30433fb5941681b913a]}
Many - Many
products:
  { _id: ObjectId(4c4ca23933fb5941681b912e),
    name: Sumatra Dark Roast,
    category_ids: [ ObjectId(4c4ca25433fb5941681b912f),
                    ObjectId(4c4ca25433fb5941681b92af”]}
 
categories:
  { _id: ObjectId(4c4ca25433fb5941681b912f), 
    name: Indonesia, 
    product_ids: [ ObjectId(4c4ca23933fb5941681b912e),
                   ObjectId(4c4ca30433fb5941681b9130),
                   ObjectId(4c4ca30433fb5941681b913a]}

//All categories for a given product
db.categories.find({product_ids: ObjectId(4c4ca23933fb5941681b912e)})
Many - Many
products:
  { _id: ObjectId(4c4ca23933fb5941681b912e),
    name: Sumatra Dark Roast,
    category_ids: [ ObjectId(4c4ca25433fb5941681b912f),
                    ObjectId(4c4ca25433fb5941681b92af”]}
 
categories:
  { _id: ObjectId(4c4ca25433fb5941681b912f), 
    name: Indonesia, 
    product_ids: [ ObjectId(4c4ca23933fb5941681b912e),
                   ObjectId(4c4ca30433fb5941681b9130),
                   ObjectId(4c4ca30433fb5941681b913a]}

//All categories for a given product
db.categories.find({product_ids: ObjectId(4c4ca23933fb5941681b912e)})

//All products for a given category
db.products.find({category_ids: ObjectId(4c4ca25433fb5941681b912f)})
Alternative
products:
  { _id: ObjectId(4c4ca23933fb5941681b912e),
    name: Sumatra Dark Roast,
    category_ids: [ ObjectId(4c4ca25433fb5941681b912f),
                    ObjectId(4c4ca25433fb5941681b92af”]}
    
categories:
  { _id: ObjectId(4c4ca25433fb5941681b912f), 
    name: Indonesia}
Alternative
products:
  { _id: ObjectId(4c4ca23933fb5941681b912e),
    name: Sumatra Dark Roast,
    category_ids: [ ObjectId(4c4ca25433fb5941681b912f),
                    ObjectId(4c4ca25433fb5941681b92af”]}
    
categories:
  { _id: ObjectId(4c4ca25433fb5941681b912f), 
    name: Indonesia}

// All products for a given category
db.products.find({category_ids: ObjectId(4c4ca25433fb5941681b912f)})
Alternative
products:
  { _id: ObjectId(4c4ca23933fb5941681b912e),
    name: Sumatra Dark Roast,
    category_ids: [ ObjectId(4c4ca25433fb5941681b912f),
                    ObjectId(4c4ca25433fb5941681b92af”]}
    
categories:
  { _id: ObjectId(4c4ca25433fb5941681b912f), 
    name: Indonesia}

// All products for a given category
db.products.find({category_ids: ObjectId(4c4ca25433fb5941681b912f)}) 

// All categories for a given product
product = db.products.find(_id : some_id)
db.categories.find({_id : {$in : product.category_ids}})
Trees

Full Tree in Document

{ comments: [
     { author: rpb , text: ... , 
       replies: [
                   {author: Fred , text: ... ,
                    replies: []} 
       ]}
   ]}

        Pros: Single Document, Performance, Intuitive
        Cons: Hard to search, 16MB limit
Trees - continued

Parent Links
- Each node is stored as a document
- Contains the id of the parent

Child Links
- Each node contains the id s of the children
- Can support graphs (multiple parents / child)
Array of Ancestors
- Store Ancestors of a node 
    {   _id:   a }
    {   _id:   b, ancestors: [ a ], parent: a }
    {   _id:   c, ancestors: [ a, b ], parent: b }
    {   _id:   d, ancestors: [ a, b ], parent: b }
    {   _id:   e, ancestors: [ a ], parent: a }
    {   _id:   f, ancestors: [ a, e ], parent: e }
    {   _id:   g, ancestors: [ a, b, d ], parent: d }
Array of Ancestors
- Store Ancestors of a node 
    {   _id:   a }
    {   _id:   b, ancestors: [ a ], parent: a }
    {   _id:   c, ancestors: [ a, b ], parent: b }
    {   _id:   d, ancestors: [ a, b ], parent: b }
    {   _id:   e, ancestors: [ a ], parent: a }
    {   _id:   f, ancestors: [ a, e ], parent: e }
    {   _id:   g, ancestors: [ a, b, d ], parent: d }

//find all descendants of b:
db.tree2.find({ancestors: b })
Array of Ancestors
- Store Ancestors of a node 
 {   _id:   a }
 {   _id:   b, ancestors: [ a ], parent: a }
 {   _id:   c, ancestors: [ a, b ], parent: b }
 {   _id:   d, ancestors: [ a, b ], parent: b }
 {   _id:   e, ancestors: [ a ], parent: a }
 {   _id:   f, ancestors: [ a, e ], parent: e }
 {   _id:   g, ancestors: [ a, b, d ], parent: d }

//find all descendants of b:
db.tree2.find({ancestors: b })

//find all ancestors of f:
ancestors = db.tree2.findOne({_id: f }).ancestors
db.tree2.find({_id: { $in : ancestors})
Variable Keys
How to index ?
{ _id : uuid1,  	

    field1 : {   ctx1 : { ctx3 : 5, … },     	

                  ctx8 : { ctx3 : 5, … } }}	


db.MyCollection.find({ field1.ctx1.ctx3 : { $exists : true} })	


Rewrite:
{ _id : uuid1,  	

    field1 : {   key: ctx1 , value : { k:ctx3 , v : 5, … },     	

                  key: ctx8 , value : { k: ctx3 , v : 5, … } }}	

	

db.x.ensureIndex({ field1.key.k , 1})
findAndModify
Queue example

//Example: find highest priority job and mark

job = db.jobs.findAndModify({

          query: {inprogress: false},
          sort:   {priority: -1), 
          update: {$set: {inprogress: true, 
                          started: new Date()}},
          new: true})
Thanks !

More Related Content

PDF
Storing tree structures with MongoDB
PPT
Schema design short
PDF
MongoD Essentials
PDF
Building DSLs with Groovy
ODP
2011 Mongo FR - Indexing in MongoDB
PPTX
Indexing Strategies to Help You Scale
PPTX
Indexing and Query Optimization
PPT
03DOM.ppt
Storing tree structures with MongoDB
Schema design short
MongoD Essentials
Building DSLs with Groovy
2011 Mongo FR - Indexing in MongoDB
Indexing Strategies to Help You Scale
Indexing and Query Optimization
03DOM.ppt

What's hot (19)

PPTX
Rapid and Scalable Development with MongoDB, PyMongo, and Ming
PPTX
Indexing & Query Optimization
KEY
Schema Design (Mongo Austin)
KEY
Geospatial Indexing and Querying with MongoDB
PPTX
Reducing Development Time with MongoDB vs. SQL
PPTX
MongoDB and Indexes - MUG Denver - 20160329
PPTX
Django - sql alchemy - jquery
PPTX
MongoDB + Java - Everything you need to know
PPTX
Indexing and Query Optimizer (Aaron Staple)
PDF
MongoDB Europe 2016 - Debugging MongoDB Performance
PDF
Embedding a language into string interpolator
PDF
Database madness with_mongoengine_and_sql_alchemy
PDF
Optimizing Slow Queries with Indexes and Creativity
ZIP
CouchDB-Lucene
ODP
Contando uma história com O.O.
PDF
An introduction into Spring Data
PPTX
Getting started with Elasticsearch and .NET
PPTX
Sequelize
PDF
Polyglot Persistence
Rapid and Scalable Development with MongoDB, PyMongo, and Ming
Indexing & Query Optimization
Schema Design (Mongo Austin)
Geospatial Indexing and Querying with MongoDB
Reducing Development Time with MongoDB vs. SQL
MongoDB and Indexes - MUG Denver - 20160329
Django - sql alchemy - jquery
MongoDB + Java - Everything you need to know
Indexing and Query Optimizer (Aaron Staple)
MongoDB Europe 2016 - Debugging MongoDB Performance
Embedding a language into string interpolator
Database madness with_mongoengine_and_sql_alchemy
Optimizing Slow Queries with Indexes and Creativity
CouchDB-Lucene
Contando uma história com O.O.
An introduction into Spring Data
Getting started with Elasticsearch and .NET
Sequelize
Polyglot Persistence
Ad

Viewers also liked (10)

KEY
Building your first application w/mongoDB MongoSV2011
PDF
The Fine Art of Schema Design in MongoDB: Dos and Don'ts
ODP
Кратко о MongoDB
PDF
MongoDB and Schema Design
PPTX
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
PPTX
Преимущества NoSQL баз данных на примере MongoDB
KEY
MongoDB Aggregation Framework
PDF
Выбор NoSQL базы данных для вашего проекта: "Не в свои сани не садись"
PPTX
Agg framework selectgroup feb2015 v2
PDF
Webinar: 10-Step Guide to Creating a Single View of your Business
Building your first application w/mongoDB MongoSV2011
The Fine Art of Schema Design in MongoDB: Dos and Don'ts
Кратко о MongoDB
MongoDB and Schema Design
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
Преимущества NoSQL баз данных на примере MongoDB
MongoDB Aggregation Framework
Выбор NoSQL базы данных для вашего проекта: "Не в свои сани не садись"
Agg framework selectgroup feb2015 v2
Webinar: 10-Step Guide to Creating a Single View of your Business
Ad

Similar to Intro to MongoDB and datamodeling (20)

KEY
Schema Design with MongoDB
PDF
10gen Presents Schema Design and Data Modeling
PPTX
Webinar: General Technical Overview of MongoDB for Dev Teams
PDF
Starting with MongoDB
PDF
MongoDB for Coder Training (Coding Serbia 2013)
PDF
MongoDB With Style
KEY
Schema design
PPTX
MongoDB (Advanced)
KEY
Managing Social Content with MongoDB
PDF
Full metal mongo
PDF
Hands On Spring Data
PDF
Latinoware
PDF
2013-03-23 - NoSQL Spartakiade
KEY
Mongodb intro
PPTX
Choosing a Shard key
PDF
Building Apps with MongoDB
PDF
Building Your First MongoDB App
PPTX
Back to Basics Webinar 4: Advanced Indexing, Text and Geospatial Indexes
KEY
Benefits of using MongoDB: Reduce Complexity & Adapt to Changes
KEY
MongoDB at GUL
Schema Design with MongoDB
10gen Presents Schema Design and Data Modeling
Webinar: General Technical Overview of MongoDB for Dev Teams
Starting with MongoDB
MongoDB for Coder Training (Coding Serbia 2013)
MongoDB With Style
Schema design
MongoDB (Advanced)
Managing Social Content with MongoDB
Full metal mongo
Hands On Spring Data
Latinoware
2013-03-23 - NoSQL Spartakiade
Mongodb intro
Choosing a Shard key
Building Apps with MongoDB
Building Your First MongoDB App
Back to Basics Webinar 4: Advanced Indexing, Text and Geospatial Indexes
Benefits of using MongoDB: Reduce Complexity & Adapt to Changes
MongoDB at GUL

Recently uploaded (20)

PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
Spectroscopy.pptx food analysis technology
PDF
cuic standard and advanced reporting.pdf
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Empathic Computing: Creating Shared Understanding
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Encapsulation theory and applications.pdf
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPTX
sap open course for s4hana steps from ECC to s4
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
KodekX | Application Modernization Development
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Spectroscopy.pptx food analysis technology
cuic standard and advanced reporting.pdf
Encapsulation_ Review paper, used for researhc scholars
Mobile App Security Testing_ A Comprehensive Guide.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
Empathic Computing: Creating Shared Understanding
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Programs and apps: productivity, graphics, security and other tools
Encapsulation theory and applications.pdf
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Building Integrated photovoltaic BIPV_UPV.pdf
sap open course for s4hana steps from ECC to s4
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Per capita expenditure prediction using model stacking based on satellite ima...
Network Security Unit 5.pdf for BCA BBA.
KodekX | Application Modernization Development
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Agricultural_Statistics_at_a_Glance_2022_0.pdf

Intro to MongoDB and datamodeling

  • 1. Schema Design Roger Bodamer roger@analytica.com @rogerb
  • 2. A brief history of Data Modeling •  ISAM • COBOL •  Network •  Hiearchical •  Relational • 1970 E.F.Codd introduces 1st Normal Form (1NF) • 1971 E.F.Codd introduces 2nd and 3rd Normal Form (2NF, 3NF • 1974 Codd Boyce define Boyce/Codd Normal Form (BCNF) • 2002 Date, Darween, Lorentzos define 6th Normal Form (6NF) • Object
  • 3. So why model data?
  • 4. Modeling goals Goals: •  Avoid anomalies when inserting, updating or deleting •  Minimize redesign when extending the schema •  Make the model informative to users •  Avoid bias towards a particular style of query * source : wikipedia
  • 7. Some terms before we proceed RDBMS Document DBs Table Collection View / Row(s) JSON Document Index Index Join Embedding Linking across documents Partition Shard Partition Key Shard Key
  • 8. Recap Design documents that simply map to your application post  =  {author:   roger ,                  date:  new  Date(),                  text:   Down  Under... ,                  tags:  [ rockstar , men  at  work ]}
  • 9. Query operators Conditional operators: $ne, $in, $nin, $mod, $all, $size, $exists, $type, .. $lt, $lte, $gt, $gte, $ne, // find posts with any tags db.posts.find({tags: {$exists: true}})  
  • 10. Query operators Conditional operators: $ne, $in, $nin, $mod, $all, $size, $exists, $type, .. $lt, $lte, $gt, $gte, $ne, // find posts with any tags db.posts.find({tags: {$exists: true}}) Regular expressions: // posts where author starts with k db.posts.find({author: /^r*/i })  
  • 11. Query operators Conditional operators: $ne, $in, $nin, $mod, $all, $size, $exists, $type, .. $lt, $lte, $gt, $gte, $ne, // find posts with any tags db.posts.find({tags: {$exists: true}}) Regular expressions: // posts where author starts with k db.posts.find({author: /^r*/i }) Counting: // posts written by mike    db.posts.find({author:   roger }).count()  
  • 12. Extending the Schema new_comment = {author: Bruce , date: new Date(), text: Love Men at Work!!!! } new_info = { $push : {comments: new_comment}, $inc : {comments_count: 1}}  db.posts.update({_id:   ...  },  new_info)  
  • 13. Extending the Schema { _id : ObjectId(4c4ba5c0672c685e5e8aabf3), author : ”roger, date : Sat Jul 24 2010 19:47:11 GMT-0700 (PDT), text : ”Down  Under..., tags : [ ”rockstar, ”men at work ], comments_count: 1, comments : [ { author : ”Bruce, date : Sat Jul 24 2010 20:51:03 GMT-0700 (PDT), text : ” Love Men at Work!!!! } ]}
  • 14. Extending the Schema // create index on nested documents: db.posts.ensureIndex({comments.author: 1}) db.posts.find({comments.author:”Bruce”}) // find last 5 posts: db.posts.find().sort({date:-1}).limit(5) // most commented post: db.posts.find().sort({comments_count:-1}).limit(1) When sorting, check if you need an index
  • 16. Modeling Patterns Single table inheritance One to Many Many to Many Trees Queues
  • 17. Single Table Inheritance db.shapes.find() { _id: ObjectId(...), type: circle, area: 3.14, radius: 1} { _id: ObjectId(...), type: square, area: 4, d: 2} { _id: ObjectId(...), type: rect, area: 10, length: 5, width: 2} // find shapes where radius 0 db.shapes.find({radius: {$gt: 0}}) // create index db.shapes.ensureIndex({radius: 1})
  • 18. One to Many - Embedded Array / Using Array Keys - slice operator to return subset of array - hard to find latest comments across all documents
  • 19. One to Many - Embedded Array / Array Keys - slice operator to return subset of array - hard to find latest comments across all documents - Embedded tree - Single document - Natural
  • 20. One to Many - Embedded Array / Array Keys - slice operator to return subset of array - hard to find latest comments across all documents - Embedded tree - Single document - Natural - Normalized (2 collections) - most flexible - more queries
  • 21. Many - Many Example: - Product can be in many categories - Category can have many products Products Category - product_id - category_id Prod_Categories -  id -  product_id -  category_id
  • 22. Many – Many products: { _id: ObjectId(4c4ca23933fb5941681b912e), name: Sumatra Dark Roast, category_ids: [ ObjectId(4c4ca25433fb5941681b912f), ObjectId(4c4ca25433fb5941681b92af”]}
  • 23. Many – Many products: { _id: ObjectId(4c4ca23933fb5941681b912e), name: Sumatra Dark Roast, category_ids: [ ObjectId(4c4ca25433fb5941681b912f), ObjectId(4c4ca25433fb5941681b92af”]} categories: { _id: ObjectId(4c4ca25433fb5941681b912f), name: Indonesia, product_ids: [ ObjectId(4c4ca23933fb5941681b912e), ObjectId(4c4ca30433fb5941681b9130), ObjectId(4c4ca30433fb5941681b913a]}
  • 24. Many - Many products: { _id: ObjectId(4c4ca23933fb5941681b912e), name: Sumatra Dark Roast, category_ids: [ ObjectId(4c4ca25433fb5941681b912f), ObjectId(4c4ca25433fb5941681b92af”]} categories: { _id: ObjectId(4c4ca25433fb5941681b912f), name: Indonesia, product_ids: [ ObjectId(4c4ca23933fb5941681b912e), ObjectId(4c4ca30433fb5941681b9130), ObjectId(4c4ca30433fb5941681b913a]} //All categories for a given product db.categories.find({product_ids: ObjectId(4c4ca23933fb5941681b912e)})
  • 25. Many - Many products: { _id: ObjectId(4c4ca23933fb5941681b912e), name: Sumatra Dark Roast, category_ids: [ ObjectId(4c4ca25433fb5941681b912f), ObjectId(4c4ca25433fb5941681b92af”]} categories: { _id: ObjectId(4c4ca25433fb5941681b912f), name: Indonesia, product_ids: [ ObjectId(4c4ca23933fb5941681b912e), ObjectId(4c4ca30433fb5941681b9130), ObjectId(4c4ca30433fb5941681b913a]} //All categories for a given product db.categories.find({product_ids: ObjectId(4c4ca23933fb5941681b912e)}) //All products for a given category db.products.find({category_ids: ObjectId(4c4ca25433fb5941681b912f)})
  • 26. Alternative products: { _id: ObjectId(4c4ca23933fb5941681b912e), name: Sumatra Dark Roast, category_ids: [ ObjectId(4c4ca25433fb5941681b912f), ObjectId(4c4ca25433fb5941681b92af”]} categories: { _id: ObjectId(4c4ca25433fb5941681b912f), name: Indonesia}
  • 27. Alternative products: { _id: ObjectId(4c4ca23933fb5941681b912e), name: Sumatra Dark Roast, category_ids: [ ObjectId(4c4ca25433fb5941681b912f), ObjectId(4c4ca25433fb5941681b92af”]} categories: { _id: ObjectId(4c4ca25433fb5941681b912f), name: Indonesia} // All products for a given category db.products.find({category_ids: ObjectId(4c4ca25433fb5941681b912f)})
  • 28. Alternative products: { _id: ObjectId(4c4ca23933fb5941681b912e), name: Sumatra Dark Roast, category_ids: [ ObjectId(4c4ca25433fb5941681b912f), ObjectId(4c4ca25433fb5941681b92af”]} categories: { _id: ObjectId(4c4ca25433fb5941681b912f), name: Indonesia} // All products for a given category db.products.find({category_ids: ObjectId(4c4ca25433fb5941681b912f)}) // All categories for a given product product = db.products.find(_id : some_id) db.categories.find({_id : {$in : product.category_ids}})
  • 29. Trees Full Tree in Document { comments: [ { author: rpb , text: ... , replies: [ {author: Fred , text: ... , replies: []} ]} ]} Pros: Single Document, Performance, Intuitive Cons: Hard to search, 16MB limit
  • 30. Trees - continued Parent Links - Each node is stored as a document - Contains the id of the parent Child Links - Each node contains the id s of the children - Can support graphs (multiple parents / child)
  • 31. Array of Ancestors - Store Ancestors of a node { _id: a } { _id: b, ancestors: [ a ], parent: a } { _id: c, ancestors: [ a, b ], parent: b } { _id: d, ancestors: [ a, b ], parent: b } { _id: e, ancestors: [ a ], parent: a } { _id: f, ancestors: [ a, e ], parent: e } { _id: g, ancestors: [ a, b, d ], parent: d }
  • 32. Array of Ancestors - Store Ancestors of a node { _id: a } { _id: b, ancestors: [ a ], parent: a } { _id: c, ancestors: [ a, b ], parent: b } { _id: d, ancestors: [ a, b ], parent: b } { _id: e, ancestors: [ a ], parent: a } { _id: f, ancestors: [ a, e ], parent: e } { _id: g, ancestors: [ a, b, d ], parent: d } //find all descendants of b: db.tree2.find({ancestors: b })
  • 33. Array of Ancestors - Store Ancestors of a node { _id: a } { _id: b, ancestors: [ a ], parent: a } { _id: c, ancestors: [ a, b ], parent: b } { _id: d, ancestors: [ a, b ], parent: b } { _id: e, ancestors: [ a ], parent: a } { _id: f, ancestors: [ a, e ], parent: e } { _id: g, ancestors: [ a, b, d ], parent: d } //find all descendants of b: db.tree2.find({ancestors: b }) //find all ancestors of f: ancestors = db.tree2.findOne({_id: f }).ancestors db.tree2.find({_id: { $in : ancestors})
  • 34. Variable Keys How to index ? { _id : uuid1,   field1 : {   ctx1 : { ctx3 : 5, … },     ctx8 : { ctx3 : 5, … } }} db.MyCollection.find({ field1.ctx1.ctx3 : { $exists : true} }) Rewrite: { _id : uuid1,   field1 : {   key: ctx1 , value : { k:ctx3 , v : 5, … },     key: ctx8 , value : { k: ctx3 , v : 5, … } }} db.x.ensureIndex({ field1.key.k , 1})
  • 35. findAndModify Queue example //Example: find highest priority job and mark job = db.jobs.findAndModify({
 query: {inprogress: false}, sort: {priority: -1), update: {$set: {inprogress: true, started: new Date()}}, new: true})