mongodb
|

Mastering MongoDB Schema Design: Navigating One-to-N Relationships

Mastering MongoDB Schema Design: Navigating One-to-N Relationships

Introduction

“I have lots of experience with SQL and normalized databases, but I’m just a beginner with MongoDB. How do I model a one-to-N relationship?” This is one of the more common questions I get from users attending MongoDB office hours.

I don’t have a short answer to this question, because there isn’t just one way, there’s a whole rainbow’s worth of ways. MongoDB has a rich and nuanced vocabulary for expressing what, in SQL, gets flattened into the term “One-to-N.” Let me take you on a tour of your choices in modeling One-to-N relationships.

Modeling One-to-Few Relationships

An example of “one-to-few” might be the addresses for a person. This is a good use case for embedding. You’d put the addresses in an array inside of your Person object:

{
  name: 'Kate Monster',
  ssn: '123-456-7890',
  addresses : [
    { street: '123 Sesame St', city: 'Anytown', cc: 'USA' },
    { street: '123 Avenue Q', city: 'New York', cc: 'USA' }
  ]
}

This design has all of the advantages and disadvantages of embedding. The main advantage is that you don’t have to perform a separate query to get the embedded details; the main disadvantage is that you have no way of accessing the embedded details as stand-alone entities.

Modeling One-to-Many Relationships

An example of “one-to-many” might be parts for a product in a replacement parts ordering system. Each product may have up to several hundred replacement parts, but never more than a couple thousand or so. This is a good use case for referencing. You’d put the ObjectIDs of the parts in an array in the product document.

// Part document
{
  _id : ObjectID('AAAA'),
  partno : '123-aff-456',
  name : '#4 grommet',
  qty: 94,
  cost: 0.94,
  price: 3.99
}

// Product document
{
  name : 'left-handed smoke shifter',
  manufacturer : 'Acme Corp',
  catalog_number: 1234,
  parts : [
    ObjectID('AAAA'), // reference to the #4 grommet above
    ObjectID('F17C'), // reference to a different Part
    ObjectID('D2AA')
  ]
}

You would then use an application-level join to retrieve the parts for a particular product.

Modeling One-to-Squillions Relationships

An example of “one-to-squillions” might be an event logging system that collects log messages for different machines. This is the classic use case for “parent-referencing.” You’d have a document for the host, and then store the ObjectID of the host in the documents for the log messages.

// Host document
{
  _id : ObjectID('AAAB'),
  name : 'goofy.example.com',
  ipaddr : '127.66.66.66'
}

// Log message document
{
  time : ISODate("2014-03-28T09:42:41.382Z"),
  message : 'cpu is on fire!',
  host: ObjectID('AAAB') // Reference to the Host
}

Conclusion

In this blog post, we’ve explored the nuanced approaches to modeling one-to-N relationships in MongoDB, from embedding to referencing and beyond. By understanding the different scenarios and their trade-offs, you can design efficient, scalable schemas that meet the needs of your data-driven applications.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *