Modeling Relationships in MongoDB: A Guide to One-to-One, One-to-Many, and Many-to-Many

Learn how to effectively represent relationships between documents in MongoDB using embedded documents and references. This guide will explore the different types of relationships (one-to-one, one-to-many, and many-to-many) and provide practical examples to help you choose the most suitable approach for your data modeling needs.



Relations in MongoDB: One-to-One, One-to-Many, Many-to-Many

In MongoDB, relationships between documents can be implemented in two main ways: using embedded documents or references to documents in another collection.

Implement Relation using Embedded Document

Embed related data directly within the document. For instance, an address can be embedded within an employee document.

Example: Relation using Embedded Document

db.employee.insertOne({
    _id: ObjectId("32521df3f4948bd2f54218"),
    firstName: "John",
    lastName: "King",
    email: "john.king@abc.com",
    salary: "33000",
    DoB: new Date('Mar 24, 2011'),
    address: { 
        street: "Upper Street",
        house: "No 1",
        city: "New York",
        country: "USA"
    }
})

Implement Relation using Reference

Use references to link documents from different collections. For example, create an address collection and reference it in the employee collection.

Example: Implement One-to-One Relation using Reference

db.address.insertOne({
    _id: 101,
    street: "Upper Street",
    house: "No 1",
    city: "New York",
    country: "USA"
})

db.employee.insertOne({
    firstName: "John",
    lastName: "King",
    email: "john.king@abc.com",
    salary: "33000",
    DoB: new Date('Mar 24, 2011'),
    address: 101
})

In this example, the address field in the employee document references the _id in the address collection, establishing a one-to-one relationship.

To retrieve related data, use the following steps:

Example: Find Related Documents

var addrId = db.employee.findOne({ firstName: 'John' }).address;
db.address.findOne({ _id: addrId });

Alternatively, use the $lookup stage in the aggregation pipeline to join collections:

Example: $lookup to Get Related Documents

db.employee.aggregate([
    { $lookup: {
        from: 'address',
        localField: 'address',
        foreignField: '_id',
        as: 'addr'
    }}
])
Output

[
  {
    _id: ObjectId("617a75c013dceca5c350d52f"),
    firstName: 'John',
    lastName: 'King',
    email: 'john.king@abc.com',
    salary: '33000',
    DoB: ISODate("2011-03-23T18:30:00.000Z"),
    address: 101,
    addr: [
      {
        _id: 101,
        street: 'Upper Street',
        house: 'No 1',
        city: 'New York',
        country: 'USA'
      }
    ]
  }
]

Similarly, you can implement one-to-many and many-to-many relations using these techniques.