Запити даних у MongoDB за допомогою Laravel: від основ до просунутих технік

Перекладено ШІ 0 Laravel News 26 червня, 2026

Як поєднати гнучкість MongoDB із потужним функціоналом Laravel для створення сучасних та масштабованих проектів? Опануйте мистецтво побудови запитів — від базового Eloquent до складних агрегацій та оптимізації продуктивності.

MongoDB стала однією з найпопулярніших NoSQL-баз даних завдяки своїй гнучкій документоорієнтованій структурі. На відміну від традиційних SQL-баз, що зберігають дані в рядках і таблицях, MongoDB використовує JSON-подібні документи. Це робить її ідеальним рішенням для сучасних застосунків, де критично важливими є гнучкість схеми, вкладені дані та масштабованість.

Laravel, своєю чергою, є одним із найпопулярніших PHP-фреймворків. Він пропонує розробникам чистий, експресивний синтаксис і потужні інструменти, як-от Eloquent ORM, middleware та artisan-команди. Поєднуючи Laravel із MongoDB, ви отримуєте найкраще з обох світів: надійний PHP-фреймворк і надзвичайно гнучку базу даних.

У цій статті ми розглянемо роботу з запитами у MongoDB за допомогою Laravel — від основ до прогресивних технік, оптимізації продуктивності та стратегій тестування. Наприкінці ви чітко розумітимете, як ефективно будувати запити до MongoDB у межах вашого проєкту.

# Налаштування MongoDB у Laravel

Перш ніж писати запити, необхідно сконфігурувати проект. Цей етап гарантує, що Laravel зможе взаємодіяти з MongoDB так само просто, як із MySQL або PostgreSQL. Пакет MongoDB Laravel розширює стандартний рівень роботи з БД, додаючи підтримку колекцій, документів та специфічних операторів MongoDB.

# Крок 1: Встановлення пакета

Встановіть пакет MongoDB Laravel через Composer. На момент написання статті рекомендованою версією є ^5.5, що забезпечує сумісність із Laravel 11 та PHP 8.3. Завжди перевіряйте офіційну документацію щодо актуальних версій.

composer require mongodb/laravel-mongodb:^5.5

# Крок 2: Налаштування змінних оточення

Додайте дані для підключення у файл .env. Якщо ви використовуєте MongoDB Atlas, рядок підключення можна знайти в панелі керування кластером. Він містить хост, ім'я користувача та пароль.

DB_CONNECTION=mongodb
MONGODB_URI="mongodb+srv://<username>:<password>@cluster0.mongodb.net"
MONGODB_DATABASE=laravel_mongo_demo
  • MONGODB_URI: Повний рядок підключення. Atlas використовує формат +srv, тоді як локальна база може виглядати як mongodb://127.0.0.1:27017.
  • MONGODB_DATABASE: Назва бази даних за замовчуванням.

Якщо ви вперше працюєте з MongoDB Atlas, скористайтеся офіційним гайдом Getting Started для створення кластера та налаштування доступу за IP.

# Крок 3: Оновлення конфігурації бази даних

Додайте конфігурацію MongoDB у файл config/database.php, щоб Laravel міг використовувати змінні з .env:

'mongodb' => [
    'driver' => 'mongodb',
    'dsn' => env('MONGODB_URI'),
    'database' => env('MONGODB_DATABASE'),
],

Це вказує Laravel спрямовувати запити через драйвер MongoDB, коли обрано відповідне підключення. Детальніші інструкції завжди доступні в офіційній документації проекту.

# Крок 4: Створення MongoDB-моделі

Моделі в MongoDB виконують ту ж роль, що і в SQL, але вони мають наслідувати спеціальний базовий клас. Наприклад, створимо модель Post:

php artisan make:model Post

Відредагуйте створений клас, щоб він розширював MongoDB\Laravel\Eloquent\Model:

use MongoDB\Laravel\Eloquent\Model;
 
class Post extends Model
{
    protected $connection = 'mongodb';
    protected $collection = 'posts';
    protected $fillable = ['title','body','author','status','created_at'];
}

Тут:

  • connection вказує на назву підключення.
  • collection визначає колекцію в MongoDB (аналог таблиці в SQL).
  • fillable дозволяє масове заповнення полів при створенні документа.

Вивчення вихідного коду базового класу Model допоможе краще зрозуміти доступні методи та властивості. Не бійтеся досліджувати код пакетів — він добре документований.

# Крок 5: Швидкий тест підключення

Найпростіше перевірити налаштування через Laravel Tinker або швидкий маршрут у контролері.

Варіант А: Laravel Tinker

Tinker — це REPL, який дозволяє виконувати код Laravel в інтерактивному режимі.

php artisan tinker
Post::create([
  'title' => 'First Post',
  'body' => 'Testing MongoDB with Laravel.',
  'author' => 'Admin',
  'status' => 'published'
]);
 
Post::all();

Варіант Б: Тестовий route

Ви також можете використати просте замикання (closure) у файлі маршрутів:

// routes/web.php
Route::get('/test-mongo', function () {
    Post::create([
      'title' => 'First Post',
      'body' => 'Testing MongoDB with Laravel.',
      'author' => 'Admin',
      'status' => 'published'
    ]);
    return Post::all();
});

Відкрийте /test-mongo у браузері, щоб переконатися, що дані записуються та зчитуються. Перевірити результат можна також через MongoDB Compass або панель Atlas.

# Основи побудови запитів

Laravel пропонує два основні способи взаємодії з MongoDB: query builder та Eloquent ORM. Вибір залежить від балансу між зручністю та продуктивністю.

# Query builder проти Eloquent ORM

  • Eloquent ORM сприймає кожен документ як об'єкт моделі. Це забезпечує читабельність, підтримку зв'язків та бізнес-логіки (accessors, mutators). Ідеально для роботи з постами, користувачами або коментарями.
  • Query builder — це легший рівень, що працює з колекціями напряму. Він повертає масиви замість об'єктів. Підходить для аналітики або запитів, де критична швидкість і мінімальне споживання пам'яті.

Найкраща практика — починати з ORM і переходити на query builder лише там, де виникають проблеми з продуктивністю.

# Створення документів

Використання Eloquent ідентичне до SQL. Ви просто викликаєте метод create у класу моделі:

Post::create([
    'title' => 'Second Post',
    'body' => 'Inserted with Eloquent.',
    'author' => 'Jane Doe',
    'status' => 'draft',
]);

При використанні query builder через фасад DB синтаксис дещо детальніший:

DB::connection('mongodb')->collection('posts')->insert([
    'title' => 'Third Post',
    'body' => 'Inserted with Query Builder.',
    'author' => 'John Doe',
    'status' => 'published',
]);

# Читання документів

Метод all() в Eloquent повертає всі записи колекції:

$posts = Post::all();

Результатом буде колекція екземплярів Post. У query builder аналогічний результат (але у вигляді об'єктів) дає метод get():

$posts = DB::connection('mongodb')->collection('posts')->get();

Для пошуку окремих записів використовуйте find() або фільтри:

$post = Post::find($id); // пошук за _id
$first = Post::where('status', 'published')->first(); // перший відповідний документ

# Оновлення та видалення

Операції оновлення та видалення вимагають попередньої фільтрації записів:

// Оновлення
Post::where('status', 'draft')->update(['status' => 'published']);
 
// Видалення
Post::where('author', 'John Doe')->delete();

# Ключові методи запитів

Для реальних завдань базового CRUD замало. Інтеграція Laravel із MongoDB підтримує широкий набір інструментів для фільтрації.

# Фільтрація з where() та orWhere()

$posts = Post::where('status', 'published')
    ->where('author', 'Jane Doe')
    ->get();

Ланцюжок where() об'єднує умови через "І". Якщо ж потрібно використати "АБО", застосовуйте orWhere():

$posts = Post::where('status', 'draft')
    ->orWhere('author', 'Admin')
    ->get();

# Робота з масивами та діапазонами

// Фільтрація за списком значень
$posts = Post::whereIn('status', ['draft','review'])->get();
 
// Фільтрація за діапазоном (дати, числа)
$recent = Post::whereBetween('created_at', [now()->subMonth(), now()])->get();

# Сортування та пагінація

$posts = Post::orderBy('created_at','desc')
    ->skip(10)
    ->take(5)
    ->get();

Це пропустить перші 10 записів і поверне наступні 5. Для повноцінної навігації зручніше використовувати вбудований метод paginate().

# Прогресивні техніки

MongoDB дозволяє зберігати вкладені об'єкти та масиви. Laravel надає зручні інструменти для роботи з ними.

# Вкладені документи та масиви

Якщо пост містить масив коментарів, ви можете шукати за їхніми полями через крапку:

// Пошук за автором будь-якого коментаря
$posts = Post::where('comments.author', 'Alice')->get();
 
// Пошук за автором першого коментаря
$posts = Post::where('comments.0.author', 'Alice')->get();

# Перевірка наявності полів та регулярні вирази

$featured = Post::where('featured','exists',true)->get();
$posts = Post::where('title','regexp','/mongodb/i')->get();

# Майстерність Aggregation Pipelines

Коли простих фільтрів недостатньо, на допомогу приходить aggregation framework. Це конвеєр обробки даних, де кожен етап трансформує документи для наступного кроку.

# Приклад: Статистика постів за категоріями

$results = Post::raw(function($c) {
    return $c->aggregate([
        ['$group' => ['_id' => '$category','count' => ['$sum' => 1]]],
        ['$sort' => ['count' => -1]]
    ]);
});

Цей запит групує пости за категоріями, підраховує їхню кількість і сортує результат за популярністю. Подібним чином можна реалізувати складні звіти, наприклад, щомісячну статистику або пошук найактивніших авторів через $lookup (аналог JOIN у SQL).

# Оптимізація продуктивності: Індексація

З ростом бази даних швидкість запитів безпосередньо залежить від індексів. Без них MongoDB змушена сканувати кожен документ (COLLSCAN), що вкрай неефективно.

# Створення індексів у міграціях

Schema::connection('mongodb')->table('posts', function ($collection) {
    $collection->index('author'); // одиничний індекс
    $collection->index(['status' => 1, 'created_at' => -1]); // складений індекс
    $collection->text(['title', 'body']); // повнотекстовий пошук
});

Використовуйте метод explain(), щоб перевірити, чи використовує ваш запит індекс (шукайте IXSCAN у результаті).

# Реальні сценарії використання

# Повнотекстовий пошук

Спершу створіть текстовий індекс, а потім використовуйте whereRaw для пошуку:

$term = request('q');
$results = Post::where('status', 'published')
    ->whereRaw(['$text' => ['$search' => $term]])
    ->limit(20)
    ->get();

# Ефективна пагінація

Для великих колекцій замість класичного offset (skip/take) краще використовувати курсорну пагінацію, яка спирається на ID останнього отриманого запису:

$results = Post::where('_id','<',$lastId)
    ->orderBy('_id','desc')
    ->take(20)
    ->get();

# Тестування запитів

Завжди використовуйте окрему базу даних для тестів. Налаштуйте її у phpunit.xml, щоб не пошкодити реальні дані.

public function test_it_filters_published_posts()
{
    Post::insert([
        ['title'=>'A','status'=>'published','created_at'=>now()],
        ['title'=>'B','status'=>'draft','created_at'=>now()],
    ]);
 
    $results = Post::where('status','published')->get();
 
    $this->assertCount(1, $results);
    $this->assertEquals('A', $results->first()->title);
}

Також корисно тестувати продуктивність, перевіряючи використання індексів через explain() прямо у тестах.

# Висновок

Поєднання MongoDB та Laravel — це потужний фундамент для сучасних проектів. Ви отримуєте звичний синтаксис Eloquent разом із безмежною гнучкістю NoSQL. Використовуючи правильні стратегії індексації, агрегації та кешування, ви зможете будувати масштабовані системи, здатні ефективно обробляти великі масиви даних.

Популярні

Інше, що варто прочитати

14 Оновлено 26 червня, 2026

Claude Agent тепер інтегрований в AI Assistant для PhpStorm

Ви коли-небудь задумувалися, як полегшити свою роботу в Laravel? У нашій статті ми розглядаємо, як інтеграція Claude Code в PhpStorm може підвищити вашу продуктивність, спростивши процес написання коду та навчання нових розробників. Читайте далі, щоб дізнатися більше про переваги та функціональність цього потужного поєднання

12 Оновлено 26 червня, 2026

Управління доступом у Filament за допомогою плагіна Shield

Дізнайтеся, як пакет Filament Shield забезпечує управління доступом до ваших панелей, ресурсів і віджетів у Laravel. Ця стаття розкриває основні можливості пакету, включаючи просту установку та підтримку багатокористувацьких середовищ — не пропустіть!

31 Оновлено 26 червня, 2026

Інтеграція Laravel Socialite з бібліотекою Google Client PHP

Ви хочете навчитися, як інтегрувати Google OAuth у вашому проекті Laravel, використовуючи Socialite? Дізнайтеся, як налаштувати доступ до сервісів Google, таких як Календар, у нашій сьогоднішній статті