Giới thiệu
Trong thế giới phát triển web, Laravel là một trong những framework PHP tốt nhất mà tôi đã trải nghiệm. Nó hoạt động hiệu quả với các cơ sở dữ liệu quan hệ như MariaDB hay PostgreSQL. Gần đây, tôi đã có cơ hội khám phá các cơ sở dữ liệu NoSQL, đặc biệt là MongoDB, với những tính năng tuyệt vời như chỉ mục TTL và tài liệu nhúng (One to Few relationships).
Một trong những sở thích của tôi là quản lý hệ thống máy chủ tại nhà. Tôi thích điều hành các dịch vụ và máy chủ của riêng mình. Tôi có nhiều dự án docker-compose và mỗi khi tôi muốn kiểm tra một dịch vụ mới, việc quản lý các bản cập nhật trở thành một thử thách lớn. Vì vậy, tôi đã bắt đầu một dự án mới nhằm tự động quản lý các ứng dụng docker của mình trên máy chủ cá nhân mà không cần sử dụng CLI. Mặc dù CLI của docker-compose rất mạnh mẽ, nhưng tôi muốn thử các giải pháp khác không quá phức tạp như portainer. Từ đó, tôi quyết định phát triển một ứng dụng nhỏ sử dụng Filament admin để tránh phải làm việc với các mẫu, kịch bản và tất cả các công việc lặp đi lặp lại cần thiết cho một ứng dụng CRUD đơn giản. Filament cung cấp một bảng điều khiển quản trị rất đẹp và dễ dàng tùy chỉnh và tích hợp với Laravel.
Vì vậy, tôi đã quyết định làm việc trên dự án có tên Lunash và vào thời điểm tôi viết bài này, tôi vừa phát hành phiên bản 0.1 (Tôi rất mong nhận được phản hồi!). Trong quá trình làm việc với Lunash, tôi đã gặp nhiều khó khăn khi tích hợp MongoDB với Laravel và Filament, và mục đích của bài viết này là giúp các lập trình viên tránh được những khó khăn mà tôi đã gặp phải để có thể tạo ra các dự án của riêng họ với những công nghệ tuyệt vời này.
Bắt đầu
Yêu cầu hệ thống:
- PHP đã được cài đặt và cấu hình trên máy tính của bạn.
- PECL (Nếu bạn đã cài đặt PHP, có thể bạn đã có nó).
- Composer (tài liệu chính thức).
- MongoDB chạy trên máy của bạn hoặc một phiên bản từ xa (tôi đã sử dụng phiên bản cộng đồng).
Tôi cũng giả định rằng bạn có kiến thức cơ bản về Laravel và MongoDB. Nếu không, vui lòng tham khảo tài liệu chính thức của cả hai công nghệ.
Để tham khảo, tôi đã công bố mã nguồn trên kho của mình:
Tạo một dự án Laravel mới
Đầu tiên, chúng ta cần tạo một dự án Laravel mới. Tôi đã sử dụng Laravel Installer để tạo một dự án mới:
bash
laravel new <tên-dự-án>
Tôi đã sử dụng cấu hình mặc định và chọn tùy chọn no starter kit vì Filament đã đáp ứng tất cả nhu cầu của dự án này. Nếu CLI yêu cầu bạn chọn một cơ sở dữ liệu cụ thể, bạn có thể chọn bất kỳ tùy chọn nào vì chúng ta sẽ xóa nó trong các bước tiếp theo.
Cấu hình MongoDB
Bây giờ chúng ta cần cấu hình MongoDB làm cơ sở dữ liệu chính. Tài liệu chính thức của MongoDB cho Laravel đã giải thích rất rõ ràng tất cả các bước cần thiết. Tôi sẽ tóm tắt chúng ở đây:
bash
pecl install mongodb
PECL là một CLI giúp bạn dễ dàng cài đặt các mở rộng PHP và lệnh này sẽ cài đặt và cấu hình trình điều khiển MongoDB cho cài đặt PHP mặc định của bạn.
bash
composer require mongodb/laravel-mongodb
Sau đó, sử dụng Composer để quản lý các phụ thuộc, nó sẽ cài đặt gói Laravel MongoDB chính thức giúp chúng ta tích hợp trình điều khiển.
Cấu hình Laravel với MongoDB
Bây giờ chúng ta đã có tất cả các phụ thuộc cần thiết, chúng ta có thể tiến hành cấu hình cụ thể để làm cho Laravel tương thích với MongoDB.
Cập nhật cấu hình .env
Tôi đã xóa tất cả cấu hình MariaDB (hoặc bất kỳ cơ sở dữ liệu quan hệ nào khác) khỏi tệp .env và thêm các dòng sau:
bash
DB_CONNECTION=mongodb
MONGODB_DATABASE=tên-db
MONGODB_URI="mongodb://localhost:27017/"
Hãy đảm bảo rằng kết nối mongodb tồn tại trong tệp config/database.php:
php
'connections' => [
...
'mongodb' => [
'driver' => 'mongodb',
'dsn' => env('MONGODB_URI', 'mongodb://localhost:27017'),
'database' => env('MONGODB_DATABASE', 'tên-db'),
],
],
Cập nhật migrations
Chúng ta cần cập nhật các migrations của cơ sở dữ liệu để làm cho chúng hoàn toàn tương thích với MongoDB. Hãy nhớ rằng giờ đây chúng ta đang làm việc với các collection chứ không phải các bảng. Vì vậy, chúng ta cần cập nhật câu lệnh use trong các tệp migration như sau:
php
use MongoDB\Laravel\Schema\Blueprint;
Schema::create('users', function (Blueprint $collection) {
$collection->id();
... // các trường khác
$collection->timestamps();
});
Nếu bạn dự định sử dụng trình điều khiển phiên làm việc với cơ sở dữ liệu thì hãy cập nhật migration của nó như sau:
php
Schema::create('sessions', function (Blueprint $collection) {
$collection->id();
... // các trường khác
$collection->expire('expires_at', config('session.lifetime'));
});
Phương thức expire sẽ tạo một chỉ mục TTL trong trường expires_at mà sẽ tự động xóa các tài liệu sau thời gian xác định.
Bây giờ chúng ta có thể chạy lệnh migration và kiểm tra xem mọi thứ đã chạy đúng chưa:
bash
php artisan migrate
Cập nhật Model User và các Model khác
Khi chúng ta tạo ứng dụng Laravel, tệp model app/Models/User.php đã được tự động tạo. Chúng ta cần cập nhật nó để làm cho nó tương thích với MongoDB. Chúng ta chỉ cần cập nhật phụ thuộc Authenticable như sau:
php
use MongoDB\Laravel\Auth\User as Authenticatable;
class User extends Authenticatable
{
...
}
Tất cả các trait và phụ thuộc khác có thể giữ nguyên.
Nếu bạn thêm nhiều model hơn, hãy nhớ cập nhật phụ thuộc model cơ sở với: use MongoDB\Laravel\Eloquent\Model;
Cập nhật Cache Store
Mặc định, Laravel sử dụng store cơ sở dữ liệu để ghi lại các cache hits. Nếu bạn muốn sử dụng MongoDB làm nhà cung cấp cache, bạn cần thực hiện các cập nhật sau:
Trong tệp config/cache.php, cập nhật hoặc tạo một mục mới cho mongodb:
php
'mongodb' => [
'driver' => 'mongodb',
'connection' => 'mongodb',
'collection' => 'cache',
'lock_connection' => 'mongodb',
'lock_collection' => 'cache_locks',
'lock_lottery' => [2, 100],
'lock_timeout' => 86400,
],
Cập nhật tệp .env của bạn với CACHE_STORE=mongodb nếu cần.
Và cuối cùng, cập nhật migration mà chứa việc tạo bảng cache:
php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\Cache;
return new class extends Migration
{
/**
* Chạy migrations.
*/
public function up(): void
{
/** @var MongoDB\Laravel\Cache\MongoStore */
$store = Cache::store('mongodb');
$store->createTTLIndex();
$store->lock('')->createTTLIndex();
}
/**
* Hoàn tác migrations.
*/
public function down(): void
{
/** @var MongoDB\Laravel\Cache\MongoStore */
$store = Cache::store('mongodb');
$store->flush();
/** @var MongoDB\Laravel\Cache\MongoLock */
$store
->restoreLock('lunash', owner: 'app')
->forceRelease();
}
};
Migration này sẽ tự động tạo và hết hạn tất cả các tài liệu được lưu trong collection cache.
Vì chúng ta đã chạy lệnh php artisan migrate trước đó, bạn có thể chạy lệnh:
bash
php artisan migrate:fresh
để loại bỏ tất cả các collection và chạy lại tất cả các migrations.
Cài đặt Filament
Bây giờ mà chúng ta đã có tất cả các cấu hình cần thiết với MongoDB, chúng ta có thể tiếp tục cài đặt Filament admin. Bạn có thể kiểm tra tài liệu chính thức để biết hướng dẫn chi tiết. Nhưng tôi biết rằng chúng ta chỉ muốn các lệnh đơn giản để làm cho nó hoạt động. Vậy thì đây là các lệnh:
bash
composer require filament/filament:"^4.0"
Lệnh này sẽ cài đặt gói chính thức của Filament. Phiên bản 4 là phiên bản mới nhất hiện nay.
bash
php artisan filament:install --panels
Điều này sẽ tạo các bảng điều khiển quản trị mặc định cho phép bạn truy cập vào /admin hoặc bất kỳ route quản trị nào khác đã định nghĩa.
bash
php artisan make:filament-user
Cuối cùng, chạy lệnh này sẽ tạo một người dùng để đăng nhập vào trang quản trị của ứng dụng bạn:
Trang quản trị trông có vẻ trống rỗng, đúng không? Đừng lo lắng, chúng ta sẽ tạo một resource để quản lý người dùng trong phần tiếp theo.
Tạo một Resource Filament
Bây giờ mà chúng ta đã thiết lập mọi thứ, chúng ta có thể tạo một resource để quản lý người dùng. Các resource của Filament rất mạnh mẽ và dễ dàng tạo. Bạn có thể tham khảo tài liệu chính thức để biết thêm thông tin.
bash
php artisan make:filament-resource User
Sau đó, bạn sẽ có thể thấy người dùng mà chúng ta đã tạo và có tất cả các thao tác CRUD khả dụng.
Và tất nhiên với mongosh, bạn sẽ có thể thấy tài liệu mà bạn đã tạo:
bash
db.users.find()
[
{
_id: ObjectId('68d2f89c9109cb649b081532'),
name: 'Adrián HM',
email: 'dev.foe555@slmail.me',
password: '$2y$.....u',
updated_at: ISODate('2025-09-23T19:50:46.440Z'),
created_at: ISODate('2025-09-23T19:44:28.257Z')
}
]
Thêm mối quan hệ One to Few
Bây giờ mà mọi thứ đã hoạt động, chúng ta có thể tạo một model mới với mối quan hệ One to Few. Trong MongoDB, chúng ta có thể nhúng tài liệu bên trong các tài liệu khác. Điều này rất hữu ích khi bạn có một mối quan hệ không yêu cầu truy vấn riêng biệt hoặc không có khả năng mở rộng quá nhiều.
Ví dụ, một người dùng có thể có nhiều địa chỉ nhưng một địa chỉ chỉ thuộc về một người dùng. Vì vậy, chúng ta có thể nhúng các địa chỉ bên trong tài liệu người dùng.
bash
php artisan make:model Address
Bạn có nhớ rằng chúng ta đang làm việc với các collection chứ không phải các bảng không? Vì vậy, migration là không cần thiết. Chúng ta chỉ cần cập nhật model Address như sau:
php
<?php
namespace App\Models;
use MongoDB\Laravel\Eloquent\Model;
class Address extends Model
{
protected $fillable = [
'street',
'city',
'state',
'zip_code',
];
}
Sau đó, chúng ta cần cập nhật model User để thêm mối quan hệ mới:
php
use MongoDB\Laravel\Relations\EmbedsMany;
...
protected $fillable = [
...
'addresses',
];
public function addresses(): EmbedsMany
{
return $this->embedsMany(Address::class);
}
Bây giờ chúng ta có thể cập nhật UserResource để thêm mối quan hệ địa chỉ. Chúng ta cần cập nhật app/Filament/Resources/Users/Schemas/UserForm.php và thêm một trường Repeater như sau:
php
public static function configure(Schema $schema): Schema
{
return $schema
->components([
...
Repeater::make('addresses')
->schema([
TextInput::make('street')->required(),
TextInput::make('city')->required(),
TextInput::make('state')->required(),
TextInput::make('zip_code')->required(),
])
->columnSpanFull()
->columns(2)
]);
}
Như bạn thấy, thật dễ dàng để thêm một tài liệu nhúng mới với Filament.
Và kiểm tra với mongosh, chúng ta có thể thấy các địa chỉ mới được nhúng trong tài liệu người dùng:
bash
db.users.find()
[
{
_id: ObjectId('68d4699ca2f00456ca042612'),
name: 'Adrián HM',
email: 'dev.foe555@slmail.me',
password: "$2y$10$.....u",
updated_at: ISODate('2025-09-24T22:14:49.202Z'),
created_at: ISODate('2025-09-24T21:58:52.165Z'),
addresses: [
{
street: 'En algún lugar de la mancha',
city: 'De cuyo nombre',
state: 'No quiero acordarme',
zip_code: '12345'
}
]
}
]
Kết luận
Đó là tất cả, bạn có thể dễ dàng tích hợp MongoDB với Laravel và Filament. Xin nhắc lại rằng Filament không chính thức hỗ trợ MongoDB, vì vậy nếu bạn dự định sử dụng nó trong sản xuất, hãy kiểm tra tất cả các tính năng mà bạn dự định sử dụng. Để biết thêm thông tin, hãy tham khảo tài liệu chính thức của tất cả các công nghệ đã được mô tả trong bài viết này.
Cảm ơn bạn đã đọc! Nếu bạn có bất kỳ câu hỏi hoặc phản hồi nào, vui lòng cho tôi biết.