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
Battle Ready Laravel

The ultimate guide to auditing, testing, fixing and improving your Laravel applications so you can build better apps faster and with more confidence.

Visit Battle Ready Laravel
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
Cut PHP Code Review Time & Bugs into Half with CodeRabbit logo

Cut PHP Code Review Time & Bugs into Half with CodeRabbit

CodeRabbit is an AI-powered code review tool that specializes in PHP and Laravel, running PHPStan and offering automated PR analysis, security checks, and custom review features while remaining free for open-source projects.

Cut PHP Code Review Time & Bugs into Half with CodeRabbit
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
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
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
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 →
Laravel 12.44 Adds HTTP Client afterResponse() Callbacks image

Laravel 12.44 Adds HTTP Client afterResponse() Callbacks

Read article
Handle Nested Data Structures in PHP with the Data Block Package image

Handle Nested Data Structures in PHP with the Data Block Package

Read article
Detect and Clean Up Unchanged Vendor Files with Laravel Vendor Cleanup image

Detect and Clean Up Unchanged Vendor Files with Laravel Vendor Cleanup

Read article
Seamless PropelAuth Integration in Laravel with Earhart image

Seamless PropelAuth Integration in Laravel with Earhart

Read article
Laravel API Route image

Laravel API Route

Read article
Laravel News 2025 Recap image

Laravel News 2025 Recap

Read article