openyam/hyperf-mongodb

An Eloquent-style MongoDB ORM for Hyperf with a coroutine-safe GoTask sidecar.

Maintainers

Package info

github.com/openyam/hyperf-mongodb

pkg:composer/openyam/hyperf-mongodb

Transparency log

Statistics

Installs: 4

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-08-23 12:37 UTC

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-mongodb 1.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.