$ lexprog.com

// notes from an old coder -- php, databases, and the occasional rant

[June 09, 2024] MongoDB

MongoDB Embedded Documents: Design Patterns

MongoDB Embedded Documents: Design Patterns

────────────────────────────────────────────────────────

MongoDB Embedded Documents: Design Patterns

Tip: Embed One-to-Few

If a post has 5-20 comments, embed them:

$post->comments = [
    ['user_id' => 1, 'body' => 'Great!', 'created_at' => now()],
];

Gotcha: 16MB Document Limit

A single MongoDB document can't exceed 16MB. Unbounded growth (like unlimited comments) needs references.

Tip: Embed for Co-Access

If you always read parent and children together, embed. Avoids extra queries.

Gotcha: Updating Nested Documents

Post::where('_id', $id)->update(['comments.0.body' => 'New text']);

Dot notation for nested updates. Positional $ operator for dynamic indices.

Tip: Array of Subdocuments

Post::raw(fn($c) => $c->updateOne(
    ['_id' => $id],
    ['$push' => ['comments' => ['user_id' => 2, 'body' => 'Nice']]]
));

Gotcha: Embedding Makes Indexing Harder

You can index nested fields: comments.user_id. But compound indexes on nested arrays have limitations.

Tip: Embed or Reference? The 80/20 Rule

If you always access data together, embed it. If you access it independently, reference it. The 16MB document size limit is the hard boundary — stay under 1MB for most documents.

Tip: Index Your Query Patterns, Not All Fields

Creating indexes on every field wastes RAM. Use explain() to find in-memory sorts and collection scans. Index only what your actual queries filter on.

Gotcha: No Transaction Rollback for Index Builds

Building an index on a large collection can take hours. If it fails midway, the partial index is silently discarded. Plan index builds during maintenance windows.

Senior Insight

Embedded documents are MongoDB's superpower, but they require careful design. I've seen documents embedded three levels deep, making updates to nested fields complex and error-prone. The positional operator $ and $[] help with array updates, but deeply nested documents are hard to query and reason about. My rule: max two levels of nesting. Beyond that, use references. A readable document structure is worth more than the theoretical performance gain of deep embedding.

Source: MongoDB Developer Center (https://www.mongodb.com/developer/), MongoDB Engineering Blog (https://www.mongodb.com/blog/channel/engineering-blog), Studio 3T Blog (https://studio3t.com/blog/)

────────────────────────────────────────────────────────
<-- back to posts