openyam / hyperf-mongodb
An Eloquent-style MongoDB ORM for Hyperf with a coroutine-safe GoTask sidecar.
Requires
- php: >=8.1
- ext-mongodb: ^1.21 || ^2.0
- ext-swoole: >=5.0
- hyperf/collection: ^3.1
- hyperf/config: ^3.1
- hyperf/context: ^3.1
- hyperf/contract: ^3.1
- hyperf/di: ^3.1
- hyperf/event: ^3.1
- hyperf/gotask: ^3.0
- hyperf/macroable: ^3.1
- hyperf/paginator: ^3.1
- hyperf/stringable: ^3.1
- nesbot/carbon: ^2.72 || ^3.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- hyperf/testing: ^3.1
- mockery/mockery: ^1.6
- phpstan/phpstan: ^1.12 || ^2.0
- phpunit/phpunit: ^10.5
This package is auto-updated.
Last update: 2026-08-23 13:06:17 UTC
README
openyam/hyperf-mongodb is an Eloquent-style MongoDB ORM for Hyperf 3.1. It uses a
precompiled GoTask sidecar by default so MongoDB network I/O does not block a
Swoole worker. A synchronous ext-mongodb driver is also available explicitly
for tests, CLI tools, and unsupported development platforms.
Requirements
- PHP 8.1+
- Hyperf 3.1
- Swoole 5+
ext-mongodb1.21 or 2.x- MongoDB Server 7.0 or 8.0
- Linux amd64 or arm64 for the default GoTask driver
The package does not depend on reasno/fastmongo or mongodb/mongodb.
Installation
composer require openyam/hyperf-mongodb php bin/hyperf.php vendor:publish openyam/hyperf-mongodb
Configure the connection with environment variables:
MONGODB_DRIVER=gotask MONGODB_URI=mongodb://127.0.0.1:27017 MONGODB_DATABASE=hyperf MONGODB_CONNECT_TIMEOUT=3s MONGODB_READ_WRITE_TIMEOUT=60s
The GoTask driver is intentionally fail-fast. It never falls back to the synchronous driver when a binary is missing, has the wrong checksum, or runs on an unsupported platform.
For macOS development, explicitly select the native driver:
MONGODB_DRIVER=native
Native MongoDB calls are synchronous and should not be used unnoticed in a high-concurrency Hyperf worker.
Defining models
<?php declare(strict_types=1); namespace App\Model; use OpenYam\HyperfMongoDB\Model\Model; use OpenYam\HyperfMongoDB\Model\SoftDeletes; final class LoginLog extends Model { use SoftDeletes; protected ?string $table = 'login_logs'; protected array $fillable = ['user_id', 'result', 'logged_at']; protected array $casts = [ 'logged_at' => 'datetime', ]; }
Models use Hyperf conventions: $connection, $table, $fillable, $guarded,
$casts, timestamps, scopes, observers, relations, and collection results. The
MongoDB primary key remains _id and string ObjectIds are qualified
automatically.
$log = LoginLog::create(['user_id' => 1001, 'result' => 'success']); $logs = LoginLog::query() ->where('user_id', 1001) ->orderByDesc('logged_at') ->paginate(20);
Supported relation families include has-one/many, belongs-to, belongs-to-many, embedded one/many, polymorphic relations, and through relations. Query support includes raw MongoDB filters, aggregation, cursors, lazy/chunk iteration, index synchronization, and change streams.
Builder writes follow model timestamp and soft-delete semantics. In particular,
Model::query()->where(...)->delete() updates deleted_at; use forceDelete()
for a physical delete. Empty-filter bulk writes remain blocked unless explicitly
enabled. Cursor pagination, scalar aggregates, atomic updateOrInsert,
findOneAndUpdate/findOneAndReplace/findOneAndDelete, runtime casts, strict
attribute modes, and the common findOr*/firstOr* helpers are also available.
Connections
Additional named connections may be added to config/autoload/mongodb.php and
selected using a model's $connection property. Native connections may use
different URIs. The packaged GoTask sidecar owns one MongoDB client, so GoTask
connections must share the default connection URI; they may select different
databases.
Native connections running on ext-mongodb 2.x support transactions:
$manager->transaction(function ($connection) { $connection->collection('accounts')->updateOne( ['_id' => $from], ['$inc' => ['balance' => -100]], ); $connection->collection('accounts')->updateOne( ['_id' => $to], ['$inc' => ['balance' => 100]], ); });
Transactions require a replica set or sharded cluster. The current Hyperf
GoTask MongoDB protocol does not expose logical sessions, so attempting a
transaction through a GoTask connection throws
TransactionsNotSupportedException instead of silently running without a
transaction.
Nested calls on the same native connection join the active transaction; they do not create savepoints. The outer call owns commit, rollback, and session cleanup.
Observability and indexes
Every collection operation and raw command dispatches CommandExecuting,
CommandExecuted, or CommandFailed. Events include the connection,
database, collection, operation, elapsed milliseconds, and a recursively
redacted payload. Set MONGODB_SLOW_QUERY_THRESHOLD_MS to a positive number
to additionally dispatch SlowCommandExecuted for slower operations.
IndexManager::sync() compares index keys and declared options. It supports
removing stale indexes and previewing changes:
$changes = $indexManager->sync( collection: 'login_logs', definitions: $model->getIndexes(), dropStale: true, dryRun: true, );
Change streams expose getResumeToken() and retry resumable cursor failures up
to three times by default. Set resumeAttempts in the watch options to change
that limit. A value of 0 disables retries. When resuming, the latest event or
post-batch token is sent as resumeAfter; mutually exclusive starting options
are removed automatically.
cursor(), rawCursor(), and change-stream cursor instances are single-use.
They release an open server cursor when iteration ends, fails, or is stopped
early. Exceptions thrown while hydrating a model are propagated unchanged;
MongoDB command failures are reported as CursorExpiredException.
DatabaseManager::gridFS() returns a bucket with stream-based upload,
download, rename, delete, and file lookup operations. It uses the standard
GridFS <bucket>.files and <bucket>.chunks collections and works through both
drivers.
Custom drivers implementing DriverInterface must also implement
findOneAndUpdate, findOneAndReplace, and findOneAndDelete. Transactional
drivers opt in separately through TransactionalDriverInterface.
Migrating from the application-local ORM
Replace App\Mongo\MongoModel with OpenYam\HyperfMongoDB\Model\Model, rename
$collection to $table, and rename $database to $connection. Other main
class mappings are:
| Previous | Component |
|---|---|
MongoBuilder |
OpenYam\HyperfMongoDB\Model\Builder |
MongoModelCollection |
OpenYam\HyperfMongoDB\Model\Collection |
MongoFactory |
OpenYam\HyperfMongoDB\Model\Factory |
MongoCursor |
OpenYam\HyperfMongoDB\Cursor |
MongoChangeStream |
OpenYam\HyperfMongoDB\ChangeStream |
No aliases are installed into the host application's App\ namespace.
Sidecar supply chain
The package contains statically linked linux-amd64 and linux-arm64
binaries. Their source and Go module lock are under resources/sidecar; SHA-256
values are checked before startup. Release builds run bin/build-sidecars.sh
and reject a tag when rebuilt artifacts differ from the committed binaries.
Development
composer install
composer test
composer analyse
composer cs-check
composer check
Set MONGODB_URI to enable the integration test suite.