MongoDB Relationships

Introduction to Document Relationships

In MongoDB, relationships between documents can be modeled in different ways, depending on your application's requirements. Unlike relational databases, MongoDB offers flexibility in how you structure these relationships.

MongoDB Relationships

Types of Relationships in MongoDB

One-to-One Relationships

Embedded Document Pattern

Store related data within a single document for efficient reads.

// Example: User with embedded profile
{
    _id: "user123",
    name: "John Doe",
    email: "john@example.com",
    profile: {
        bio: "Software Developer",
        location: "New York",
        interests: ["coding", "reading"]
    }
}

Referenced Document Pattern

Use references to link related documents across collections.

// Users collection
{
    _id: "user123",
    name: "John Doe",
    email: "john@example.com",
    profile_id: "profile123"
}

// Profiles collection
{
    _id: "profile123",
    bio: "Software Developer",
    location: "New York",
    interests: ["coding", "reading"]
}

One-to-Many Relationships

Embedded Array Pattern

Store related documents as an array within the parent document.

// Example: User with embedded posts
{
    _id: "user123",
    name: "John Doe",
    posts: [
        {
            title: "First Post",
            content: "Hello World!",
            created_at: ISODate("2025-01-01")
        },
        {
            title: "Second Post",
            content: "MongoDB is great!",
            created_at: ISODate("2025-01-02")
        }
    ]
}

Referenced Array Pattern

Store references to related documents in an array.

// Users collection
{
    _id: "user123",
    name: "John Doe",
    post_ids: ["post1", "post2"]
}

// Posts collection
{
    _id: "post1",
    title: "First Post",
    content: "Hello World!",
    author_id: "user123"
}

Many-to-Many Relationships

Array of References Pattern

Store arrays of references in both collections.

// Users collection
{
    _id: "user123",
    name: "John Doe",
    group_ids: ["group1", "group2"]
}

// Groups collection
{
    _id: "group1",
    name: "Developers",
    member_ids: ["user123", "user456"]
}

Intermediate Collection Pattern

Use a separate collection to manage relationships.

// UserGroups collection
{
    _id: "ug1",
    user_id: "user123",
    group_id: "group1",
    joined_at: ISODate("2025-01-01"),
    role: "member"
}

Querying Related Documents

Using $lookup

Join collections in aggregation pipeline.

// Example: Get user with their posts
db.users.aggregate([
    {
        $lookup: {
            from: "posts",
            localField: "_id",
            foreignField: "author_id",
            as: "posts"
        }
    }
])

Using References

Query related documents using references.

// Example: Get user's posts
const user = db.users.findOne({ _id: "user123" });
const posts = db.posts.find({ _id: { $in: user.post_ids } });

Best Practices

Design Guidelines

  • Consider query patterns when choosing relationship types
  • Use embedding for "contains" relationships
  • Use references for "references" relationships
  • Consider data size and update frequency
  • Implement proper indexing for referenced fields
  • Plan for data growth and scalability

Common Pitfalls

  • Over-embedding large arrays
  • Not considering query patterns
  • Ignoring data growth
  • Poor indexing strategy
  • Inconsistent relationship modeling

Next Steps

Now that you understand relationships, you can explore: