MongoDB with Laravel: Using MongoDB as Database Driver

Learn to integrate MongoDB with Laravel applications, including MongoDB driver setup, Eloquent integration, and NoSQL database design patterns.

S

StalkTechie

Author

November 30, 2024
741 views

MongoDB with Laravel: Using MongoDB as Database Driver

Laravel traditionally shines with SQL databases like MySQL, but what if your app needs flexible schemas for rapid prototyping or handling unstructured data like JSON logs, user profiles, or e-commerce catalogs? Enter MongoDB-a NoSQL powerhouse. Thanks to the jenssegers/mongodb package, you can integrate MongoDB seamlessly, even using Eloquent-like syntax. This guide walks you through setup, configuration, modeling, queries, and best practices. Perfect for Laravel 11.x in 2025-think of it as giving your app a schema-less superpower without ditching Laravel's elegance.

Why MongoDB in Laravel?

Quick pros: Horizontal scaling, schemaless docs (add fields on-the-fly), native JSON handling. Cons: No joins (use embedding/aggregation), eventual consistency. Use for content management, real-time apps, or when data shapes evolve. Human note: If your team knows SQL joins intimately, ease in gradually-Mongo's denormalization can feel liberating but needs discipline to avoid data bloat.

Installation and Setup

First, install MongoDB locally or use MongoDB Atlas (cloud). Then add the package.


composer require jenssegers/mongodb
    

For Laravel 5.8+, it auto-registers. Add connection to config/database.php:


'connections' => [
    'mongodb' => [
        'driver' => 'mongodb',
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', 27017),
        'database' => env('DB_DATABASE', 'laravel_mongo'),
        'username' => env('DB_USERNAME'),
        'password' => env('DB_PASSWORD'),
        'options' => [
            'database' => 'admin' // Auth DB
        ],
    ],
],
    

Update .env:


DB_CONNECTION=mongodb
DB_HOST=127.0.0.1
DB_PORT=27017
DB_DATABASE=your_db_name
DB_USERNAME=your_user
DB_PASSWORD=your_pass
    

Service Provider (if needed for older Laravel): Add Jenssegers\Mongodb\MongodbServiceProvider::class to config/app.php. Test connection: php artisan tinker then DB::connection('mongodb')->getMongoClient();.

Eloquent Integration: Models and Schemas

Extend MongoModel instead of Eloquent. No migrations-Mongoose-like freedom.


use Jenssegers\Mongodb\Eloquent\Model;

class Product extends Model
{
    protected $connection = 'mongodb';
    protected $collection = 'products';  // Collection name
    protected $fillable = ['name', 'price', 'tags', 'specs'];

    // Embed relations
    public function reviews()
    {
        return $this->embedsMany(Review::class);
    }
}

class Review extends Model
{
    protected $connection = 'mongodb';
    protected $fillable = ['rating', 'comment'];
}
    

Create docs like Eloquent: Product::create(['name' => 'Laptop', 'specs' => ['ram' => '16GB']]);. IDs are ObjectId by default-flexible nesting for specs or metadata.

CRUD Operations and Queries

Syntax mirrors Eloquent, but with Mongo operators.

Basic CRUD


// Create
$product = new Product;
$product->name = 'Phone';
$product->tags = ['mobile', '5G'];
$product->save();

// Read
$products = Product::all();
$cheap = Product::where('price', '<', 500)->get();

// Update
Product::where('name', 'Phone')->update(['price' => 800]);

// Delete
Product::where('price', '>', 1000)->delete();
    

Advanced Queries

Use raw Mongo expressions:


// Aggregation
$stats = Product::raw(function($collection) {
    return $collection->aggregate([
        ['$group' => ['_id' => '$category', 'avgPrice' => ['$avg' => '$price']]],
    ]);
});

// Geo queries (if location data)
Product::where('location', 'near', [
    '$geometry' => ['type' => 'Point', 'coordinates' => [-73.99, 40.75]],
    '$maxDistance' => 1000
])->get();
    

Indexes: php artisan make:index products_name_index --field=name (or manually in Mongo shell: db.products.createIndex({name: 1})).

Relationships in NoSQL Style

No joins-embed or reference.

  • EmbedsOne/EmbedsMany: For contained data (e.g., product embeds reviews).
  • 
    $product = Product::find($id);
    $product->reviews()->create(['rating' => 5, 'comment' => 'Great!']);
            
  • References: Manual IDs for cross-collection (use populate in queries if needed via raw).

Aggregation Pipeline for complex: Lookup stage simulates joins.

Database Design Patterns

  • Denormalization: Duplicate data (e.g., user name in orders) for speed-update via events.
  • Bucket Pattern: For time-series (group logs by hour).
  • Schema Validation: Enforce in Mongo: db.createCollection('products', { validator: { $jsonSchema: {...} } }).
  • Migrations Alternative: Use scripts or Laravel packages like doctrine/dbal for versioning, but embrace schemaless.

Tip: Start with embedding for 1:many small relations; reference for large/independent.

Performance and Best Practices

  • Indexing: On query fields-analyze with explain() in Mongo shell.
  • Connection Pooling: Handled by driver; set maxPoolSize in options.
  • Security: Enable auth, use roles, TLS. In Laravel, sanctum for API proctection.
  • Backup: mongodump or Atlas snapshots.
  • Testing: Spin up Mongo in Docker for CI: services: mongodb: in phpunit.xml.
  • Hybrid: Mix with MySQL-set per-model connection.

Pitfall: Transactions in Mongo 4.0+ work, but wrap in DB::transaction()-use sparingly for cross-doc consistency.

Deployment and Scaling

Dockerize: Add mongo image in compose. Scale with replicas in Atlas. Monitor with Compass or Datadog. For big data, sharding on keys like user_id.

Integrating MongoDB breathes flexibility into Laravel-ideal for agile teams. Experiment in a feature branch, profile queries, and remember: NoSQL trades ACID for speed. Check jenssegers docs for updates, and join Laravel Mongo communities for war stories. Happy querying!

Share this post:

Related Articles

Discussion

0 comments

Please log in to join the discussion.

Login to Comment