Tinkerwell - The PHP Scratchpad

Introduction to MongoDB & Laravel-MongoDB Setup

Last updated on by

Introduction to MongoDB & Laravel-MongoDB Setup image

By the end of this tutorial, you'll be able to:

  • Understand MongoDB fundamentals and its advantages over traditional SQL databases.
  • Set up a Laravel project with MongoDB integration.
  • Create polymorphic models using MongoDB.
  • Build a complete developer blog application with CRUD operations.
  • Implement advanced features like search and content categorization.

What is MongoDB?

MongoDB is a NoSQL (not only SQL) database that stores data as documents. A document, by definition, is a data structure storing property and value pairs, similar to JSON objects. This makes MongoDB incredibly flexible for:

  • Dynamic data schemas suited for polymorphism.
  • Data locality—“data that is accessed together should be stored together."
  • High performance with BSON (Binary JSON) storage format.

Why choose MongoDB over Traditional SQL?

What does NoSQL offer that traditional SQL doesn’t?

Key advantages:

  • Smaller storage footprint: BSON format is more efficient than rigid SQL tables.
  • No NULL value issues: MongoDB naturally handles sparse data.
  • Simplified queries: Aggregation pipelines replace complex SQL JOINs.
  • Better scalability: Horizontal scaling is built-in.

> Real-world example: In our developer blog application, we can store different content types (posts, articles, tutorials) in the same collection while maintaining different schemas for each type—something that would require multiple tables and complex JOINs in SQL.

Laravel + MongoDB = ✨

Prerequisites

Before we begin, make sure you have:

That’s how simple it is to get started!

To have an idea of what we will be building, here’s a video demo:

Project setup

Step 1: Create a new Laravel project

Open your terminal and run the following command:

 
laravel new developer-blog

You'll see an interactive setup prompt. Choose these options:

_ _
| | | |
| | __ _ _ __ __ ___ _____| |
| | / _` | '__/ _` \ \ / / _ \ |
| |___| (_| | | | (_| |\ V / __/ |
|______\__,_|_| \__,_| \_/ \___|_|
┌ Would you like to install a starter kit? ──────┐
│ - No starter kit │
────────────────────────────────┘
┌ Which testing framework do you prefer? ───────┐
│ - Pest │
└───────────────────────────────┘

Step 2: Generate application key

Navigate to your project directory and generate the application key:

 
cd developer-blog
php artisan key:generate

Why this matters: The application key is used for encrypting session data and other sensitive information in your Laravel application. Learn more.

Step 3: Install MongoDB Laravel package

Install the official MongoDB package for Laravel.

 
composer require mongodb/laravel-mongodb

Package info: This package provides MongoDB integration for Laravel's Eloquent ORM, allowing you to use familiar Laravel syntax with MongoDB.

Step 4: Configure database connection

Update your config/database.php file to include MongoDB as the default connection:

return [
'default' => env('DB_CONNECTION', 'mongodb'),
... 'connections' => [
...
'mongodb' => [
'driver' => 'mongodb',
'dsn' => env('DB_URI'),
'database' => env('DB_DATABASE', 'laravel'),
],
]
]

Step 5: Environment configuration

Update your .env file with MongoDB connection details:

DB_CONNECTION=mongodb
DB_URI="YOUR_MONGODB_URI"
DB_DATABASE="YOUR_MONGODB_DB_NAME"

Step 6: Start your application

Launch the Laravel development server:

php artisan serve

You can now access your application at http://127.0.0.1:8000.

Building the models (polymorphic design)

Understanding the architecture

We'll create a polymorphic content system where different content types (posts, articles, tutorials) share common properties but have their own specific fields. This demonstrates MongoDB's flexibility perfectly.

Step 1: Create the base content model

Create the abstract base model that all content types will inherit from:

File: app/Models/Content.php

<?php
namespace App\\Models;
use MongoDB\\Laravel\\Eloquent\\Model;
 
abstract class Content extends Model
{
protected $connection = 'mongodb'; // Use MongoDB connection
protected $collection = 'contents'; // Single collection for all types
 
protected $casts = [
'tags' => 'array', // MongoDB handles arrays natively!
];
 
public function scopePublished($query)
{
return $query->where('status', 'published');
}
 
abstract public function getContentType();
}

Key concepts: You can store all content types in one collection with different schemas.

Step 2: Create content type models

Using the abstract base modell, we can now create models with different types and attributes.

File: app/Models/Article.php

<?php
namespace App\\Models;
 
class Article extends Content
{
protected $attributes = ['type' => 'article'];
 
// Article-specific fields
protected $fillable = [..., 'category', 'featured_image', 'seo_title'];
 
public function getContentType()
{
return 'article';
}
 
// Automatic SEO fallback
public function getSeoTitleAttribute($value)
{
return $value ?: $this->title;
}
}

File: app/Models/Tutorial.php

<?php
namespace App\\Models;
 
class Tutorial extends Content
{
protected $attributes = ['type' => 'tutorial'];
 
protected $casts = [
'prerequisites' => 'array', // MongoDB handles nested arrays
'steps' => 'array',
];
 
public function scopeByDifficulty($query, $level)
{
return $query->where('difficulty_level', $level);
}
}

Quick tip: You can also generate model files using Laravel's Artisan command:

php artisan make:model Post

Database seeding (optional but recommended)

Let's create sample data to work with during development. This helps you see the application in action immediately.

Step 1: Create the seeder

File: database/seeders/BlogContentSeeder.php

<?php
namespace Database\\Seeders;
use App\\Models\\Post;
use App\\Models\\Article;
use App\\Models\\Tutorial;
 
class BlogContentSeeder extends Seeder
{
public function run()
{
// Create sample Posts
Post::create([
'title' => 'Getting Started with MongoDB in Laravel',
'tags' => ['mongodb', 'laravel', 'nosql'],
'status' => 'published',
'author_name' => 'John Doe',
]);
 
// Create sample Tutorial with array fields
Tutorial::create([
'title' => 'MongoDB Setup Guide',
'difficulty_level' => 'beginner',
'prerequisites' => ['Basic PHP knowledge', 'Laravel fundamentals'],
'steps' => [
['title' => 'Install MongoDB', 'content' => 'Download and install...'],
['title' => 'Configure Laravel', 'content' => 'Update config files...']
]
]);
}
}

Step 2: Run the seeder

php artisan db:seed --class=BlogContentSeeder

Pro tip: Generate seeder files using:

php artisan make:seeder BlogContentSeeder

Building the controllers

Controllers handle the business logic and connect your models to views. Let's create controllers that showcase MongoDB's powerful query capabilities.

Key controller methods

File: app/Http/Controllers/BlogController.php

<?php
namespace App\Http\Controllers;
use App\Models\{Post, Article, Tutorial};
 
class BlogController extends Controller
{
public function index()
{
// Fetch all content types and merge them
$posts = Post::published()->get();
$articles = Article::published()->get();
$tutorials = Tutorial::published()->get();
 
$content = collect()
->merge($posts)
->merge($articles)
->merge($tutorials)
->sortByDesc('published_at');
 
return view('blog.index', compact('content'));
}
 
public function show($type, $id)
{
// Dynamic model resolution based on type
$content = match ($type) {
'post' => Post::findOrFail($id),
'article' => Article::findOrFail($id),
'tutorial' => Tutorial::findOrFail($id),
default => abort(404)
};
 
return view('blog.show', compact('content'));
}
 
public function search(Request $request)
{
$query = $request->get('q');
 
// MongoDB's flexible text search across multiple fields
$searchClosure = function($q) use ($query) {
$q->where('title', 'like', "%{$query}%")
->orWhere('body', 'like', "%{$query}%")
->orWhere('tags', 'in', [$query]); // Search in array field
};
 
$posts = Post::published()->where($searchClosure)->get();
// ... repeat for other types
}
}

Register routes

File: routes/web.php

<?php
use App\Http\Controllers\BlogController;
 
Route::prefix('blog')->name('blog.')->group(function() {
Route::get('/', [BlogController::class, 'index'])->name('index');
Route::get('/search', [BlogController::class, 'search'])->name('search');
Route::get('/{type}/{id}', [BlogController::class, 'show'])
->name('show')
->where('type', 'post|article|tutorial');
});

And to develop the UI, just work with the blade.php files as you have completed the logics development.

Advanced MongoDB features

Working with arrays and nested documents

MongoDB excels at handling complex data structures:

// Querying array fields
$tutorials = Tutorial::where('tags', 'in', ['beginner', 'mongodb'])->get();
 
// Aggregation pipeline example
$tagStats = Tutorial::raw(function($collection) {
return $collection->aggregate([
['$unwind' => '$tags'],
['$group' => [
'_id' => '$tags',
'count' => ['$sum' => 1]
]],
['$sort' => ['count' => -1]]
]);
});

Performance optimization

Add indexes to improve query performance:

use MongoDB\Laravel\Schema\Blueprint;
 
Schema::connection('mongodb')->table('contents', function (Blueprint $table) {
$table->index('type');
$table->index('status');
$table->index('tags');
$table->text(['title', 'body']); // Text index for search
});

Conclusion

You've successfully built a complete Laravel application with MongoDB that demonstrates:

  • Polymorphic data modeling with a shared collection.
  • Flexible schema design that adapts to different content types.
  • Powerful querying capabilities including array field searches.
  • Full CRUD operations with MongoDB and Laravel.

Next steps

Ready to take your MongoDB + Laravel skills further? Consider exploring:

  1. MongoDB Atlas for cloud deployment.
  2. Aggregation pipelines for complex data analysis.
  3. MongoDB transactions for data consistency.
  4. Full-text search with MongoDB's text indexes.

Additional resources

Complete project

The full source code for this tutorial is available on GitHub.


Frequently asked questions

Q: I'm getting "zsh: command not found: laravel".

A: Head to Stack Overflow for guidance!

Q: Having MongoDB connection issues?

A: Learn more about configuring IP access list entries.

Q: How do I add more fields to my models later?

A: Simply add the field names to the $fillable array in your model. MongoDB's schema-less nature means no migrations are needed!


Hope this tutorial helps you understand the power and flexibility of combining Laravel with MongoDB. Happy coding!

Lai Kai Yong photo

Full Stack Engineer

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

image
Bacancy

Outsource a dedicated Laravel developer for $3,200/month. With over a decade of experience in Laravel development, we deliver fast, high-quality, and cost-effective solutions at affordable rates.

Visit Bacancy
Curotec logo

Curotec

World class Laravel experts with GenAI dev skills. LATAM-based, embedded engineers that ship fast, communicate clearly, and elevate your product. No bloat, no BS.

Curotec
Bacancy logo

Bacancy

Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $3200/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Bacancy
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
Get expert guidance in a few days with a Laravel code review logo

Get expert guidance in a few days with a Laravel code review

Expert code review! Get clear, practical feedback from two Laravel devs with 10+ years of experience helping teams build better apps.

Get expert guidance in a few days with a Laravel code review
PhpStorm logo

PhpStorm

The go-to PHP IDE with extensive out-of-the-box support for Laravel and its ecosystem.

PhpStorm
Laravel Cloud logo

Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Cloud
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Harpoon: Next generation time tracking and invoicing logo

Harpoon: Next generation time tracking and invoicing

The next generation time-tracking and billing software that helps your agency plan and forecast a profitable future.

Harpoon: Next generation time tracking and invoicing
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit

The latest

View all →
Bagisto Visual: Theme Framework with Visual Editor for Laravel E-commerce image

Bagisto Visual: Theme Framework with Visual Editor for Laravel E-commerce

Read article
Clawdbot Rebrands to Moltbot After Trademark Request From Anthropic image

Clawdbot Rebrands to Moltbot After Trademark Request From Anthropic

Read article
Automate Laravel Herd Worktrees with This Claude Code Skill image

Automate Laravel Herd Worktrees with This Claude Code Skill

Read article
Laravel Boost v2.0 Released with Skills Support image

Laravel Boost v2.0 Released with Skills Support

Read article
Laravel Debugbar v4.0.0 is released image

Laravel Debugbar v4.0.0 is released

Read article
Radiance: Generate Deterministic Mesh Gradient Avatars in PHP image

Radiance: Generate Deterministic Mesh Gradient Avatars in PHP

Read article