PHP code example of phpdot / mongodb
1. Go to this page and download the library: Download phpdot/mongodb library . Choose the download type require .
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
phpdot / mongodb example snippets
use PHPdot\MongoDB\MongoConnection;
use PHPdot\MongoDB\Config\MongoConfig;
use PHPdot\MongoDB\Database\Database;
$connection = new MongoConnection(new MongoConfig(
hosts: 'localhost',
database: 'myapp',
));
$connection->connect();
$db = new Database($connection);
$users = $db->collection('users');
// Insert
$users->insertOne(['name' => 'Omar', 'email' => '[email protected] ']);
// Find
$user = $users->findOne(['email' => '[email protected] ']);
echo $user->name; // 'Omar'
// Fluent query
$active = $users->find()
->filter(['status' => 'active'])
->sort(['created_at' => -1])
->limit(10)
->execute();
foreach ($active as $doc) {
echo $doc->name;
}
$config = new MongoConfig(
hosts: 'localhost', // string or list of strings
port: 27017, // default port (ignored if host database
deployment: 'single', // 'single', 'replicaSet', 'sharded'
replicaSet: '', // replica set name
timeoutMs: 1000, // connection timeout
readPreference: 'primary', // read preference mode
writeConcern: 'majority', // string or int
readConcern: 'local', // read concern level
maxStalenessSeconds: -1, // -1 = no limit
tags: [], // tag sets for read preference
retryWrites: true, // retryable writes
retryReads: true, // retryable reads
maxRetries: 3, // reconnection retry attempts
options: [], // additional MongoDB URI options
);
$config = new MongoConfig(
hosts: ['mongo1.example.com', 'mongo2.example.com:27018'],
database: 'myapp',
);
// URI: mongodb://mongo1.example.com:27017,mongo2.example.com:27018
$config = new MongoConfig(
hosts: 'mongo.example.com',
username: 'admin',
password: 'p@ss w0rd!', // auto URL-encoded
database: 'myapp',
);
// URI: mongodb://admin:p%40ss%20w0rd%[email protected] :27017
$connection = new MongoConnection($config);
$connection->connect(); // connect with exponential backoff retries
$connection->isConnected(); // local flag check (no server round-trip)
$connection->ping(); // actual server ping
$connection->ensureConnected(); // throws ConnectionException if not connected
$connection->reconnect(); // close + connect
$connection->close(); // disconnect
$connection->getClient(); // MongoDB\Client
$connection->getDatabase(); // MongoDB\Database (uses config database)
$connection->getConfig(); // MongoConfig
// Single server
new MongoConfig(hosts: 'localhost', database: 'myapp');
// Replica set
new MongoConfig(
hosts: ['rs1.example.com', 'rs2.example.com', 'rs3.example.com'],
deployment: 'replicaSet',
replicaSet: 'rs0',
readPreference: 'secondaryPreferred',
);
// Sharded cluster
new MongoConfig(
hosts: ['mongos1.example.com', 'mongos2.example.com'],
deployment: 'sharded',
);
$db = new Database($connection);
$db = new Database($connection, $logger); // with query logging
$users = $db->collection('users'); // Collection instance
$result = $db->transaction(function (Database $db, Session $session) {
$db->collection('accounts')->updateOne()
->filter(['_id' => $from])
->update(['$inc' => ['balance' => -100]])
->session($session)
->execute();
$db->collection('accounts')->updateOne()
->filter(['_id' => $to])
->update(['$inc' => ['balance' => 100]])
->session($session)
->execute();
return 'transferred';
});
// $result === 'transferred'
// Transaction options
$db->transaction($callback, [
'readConcern' => new ReadConcern('snapshot'),
'writeConcern' => new WriteConcern('majority'),
]);
$result = $db->command(['ping' => 1]);
// ['ok' => 1]
$result = $db->command(['serverStatus' => 1]);
$db->createCollection('users');
$db->createCollection('validated', [
'validator' => [
'$jsonSchema' => [
'bsonType' => 'object',
'type' => 'collection', 'options' => []], ...]
$db->raw(); // MongoDB\Database escape hatch
// Single document
$result = $users->insertOne(['name' => 'Omar', 'email' => '[email protected] ']);
$result->getInsertedId(); // ObjectId
$result->getInsertedCount(); // 1
// Custom ID
$users->insertOne(['_id' => new ObjectId(), 'name' => 'Omar']);
// Multiple documents
$result = $users->insertMany([
['name' => 'Alice', 'age' => 25],
['name' => 'Bob', 'age' => 30],
['name' => 'Charlie', 'age' => 35],
]);
$result->getInsertedCount(); // 3
$result->getInsertedIds(); // [ObjectId, ObjectId, ObjectId]
// Find one — returns Document or null
$user = $users->findOne(['email' => '[email protected] ']);
$user = $users->findOne(); // first document in collection
// With options
$user = $users->findOne(
['name' => 'Omar'],
['projection' => ['name' => 1, 'email' => 1, '_id' => 0]],
);
// Full example
$cursor = $users->find()
->filter(['status' => 'active']) // array filter
->projection(['name' => 1, 'email' => 1]) // fields to return
->sort(['created_at' => -1, 'name' => 1]) // sort order
->limit(10) // max documents
->skip(20) // pagination offset
->hint('status_1_created_at_-1') // index hint (string or array)
->collation(['locale' => 'en', 'strength' => 2])
->maxTimeMS(5000) // timeout
->batchSize(100) // cursor batch size
->allowDiskUse() // large sorts
->comment('admin dashboard query') // profiler comment
->session($session) // transaction session
->option('noCursorTimeout', true) // any additional option
->execute(); // → Cursor of Documents
// Iterate results
foreach ($cursor as $doc) {
echo $doc->name;
}
// Shortcuts
$first = $users->find()->filter(['status' => 'active'])->first(); // Document|null
$count = $users->find()->filter(['status' => 'active'])->count(); // int
$plan = $users->find()->filter(['status' => 'active'])->explain(); // array
// Filter builder callback
$users->find()
->where(fn(Filter $f) => $f
->eq('status', 'active')
->gte('age', 18)
->in('tags', ['vip', 'premium'])
->or(
Filter::new()->eq('role', 'admin'),
Filter::new()->gt('score', 90),
)
)
->sort(['score' => -1])
->limit(20)
->execute();
// Debug compiled state
$query = $users->find()->filter(['status' => 'active'])->sort(['name' => 1]);
$query->getFilter(); // ['status' => 'active']
$query->getOptions(); // ['sort' => ['name' => 1]]
// Update one
$result = $users->updateOne()
->filter(['email' => '[email protected] '])
->update(['$set' => ['name' => 'Omar H.'], '$inc' => ['logins' => 1]])
->execute();
$result->getMatchedCount(); // 1
$result->getModifiedCount(); // 1
// Update with where callback
$users->updateOne()
->where(fn(Filter $f) => $f->eq('status', 'inactive')->lt('last_login', $threshold))
->update(['$set' => ['archived' => true]])
->execute();
// Upsert (insert if not found)
$users->updateOne()
->filter(['email' => '[email protected] '])
->update(['$set' => ['name' => 'New User']])
->upsert()
->execute();
// Update many
$result = $users->updateMany()
->filter(['status' => 'trial'])
->update(['$set' => ['status' => 'expired']])
->execute();
// Array filters for positional operators
$users->updateOne()
->filter(['_id' => $id])
->update(['$set' => ['items.$[elem].qty' => 0]])
->arrayFilters([['elem.status' => 'inactive']])
->execute();
// Options
$users->updateOne()
->filter(['_id' => $id])
->update(['$set' => ['name' => 'Omar']])
->hint('email_1')
->collation(['locale' => 'en'])
->session($session)
->option('bypassDocumentValidation', true)
->execute();
// Debug
$query = $users->updateOne()->filter(['x' => 1])->update(['$set' => ['y' => 2]])->upsert();
$query->getFilter(); // ['x' => 1]
$query->getUpdate(); // ['$set' => ['y' => 2]]
$query->getOptions(); // ['upsert' => true]
// Delete one
$result = $users->deleteOne()
->filter(['email' => '[email protected] '])
->execute();
$result->getDeletedCount(); // 1
// Delete with where callback
$sessions->deleteMany()
->where(fn(Filter $f) => $f->lt('expires_at', new UTCDateTime()))
->execute();
// Options
$users->deleteOne()
->filter(['_id' => $id])
->hint('email_1')
->collation(['locale' => 'en'])
->session($session)
->option('comment', 'cleanup')
->execute();
$result = $users->replaceOne(
['email' => '[email protected] '], // filter
['name' => 'Omar', 'email' => '[email protected] ', 'v' => 2], // replacement
);
$result->getMatchedCount(); // 1
$result->getModifiedCount(); // 1
// Find and update
$doc = $users->findOneAndUpdate(
['email' => '[email protected] '],
['$set' => ['last_login' => new UTCDateTime()]],
);
// $doc is the document BEFORE the update (or null if not found)
// Return the document AFTER update
$doc = $users->findOneAndUpdate(
['email' => '[email protected] '],
['$inc' => ['visits' => 1]],
['returnDocument' => \MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER],
);
// Find and replace
$doc = $users->findOneAndReplace(
['email' => '[email protected] '],
['name' => 'Omar', 'email' => '[email protected] '],
);
// Find and delete
$doc = $users->findOneAndDelete(['status' => 'expired']);
// $doc is the deleted document (or null)
$result = $users->bulkWrite([
['insertOne' => [['name' => 'New', 'age' => 20]]],
['updateOne' => [['name' => 'Existing'], ['$set' => ['active' => true]]]],
['updateMany' => [['status' => 'trial'], ['$set' => ['status' => 'expired']]]],
['replaceOne' => [['name' => 'Old'], ['name' => 'Replaced']]],
['deleteOne' => [['name' => 'Remove']]],
['deleteMany' => [['status' => 'deleted']]],
]);
$result->getInsertedCount();
$result->getMatchedCount();
$result->getModifiedCount();
$result->getDeletedCount();
$result->getUpsertedCount();
// Count with filter
$total = $users->countDocuments();
$active = $users->countDocuments(['status' => 'active']);
// Estimated count (fast, metadata-based — no filter)
$approx = $users->estimatedDocumentCount();
// Distinct values
$statuses = $users->distinct('status');
// ['active', 'inactive', 'suspended']
$names = $users->distinct('name', ['status' => 'active']);
// ['Alice', 'Bob', 'Omar']
// Raw pipeline arrays
$results = $orders->aggregate([
['$match' => ['status' => 'completed']],
['$group' => [
'_id' => '$category',
'total' => ['$sum' => '$amount'],
'count' => ['$sum' => 1],
]],
['$sort' => ['total' => -1]],
['$limit' => 10],
]);
foreach ($results as $doc) {
echo $doc->_id; // category name
echo $doc->total; // aggregated sum
}
// mongodb/mongodb's type-safe builder
use MongoDB\Builder\Stage;
use MongoDB\Builder\Accumulator;
$results = $orders->aggregate(
Stage::match(status: 'completed')
->lookup(from: 'customers', localField: 'customer_id', foreignField: '_id', as: 'customer')
->unwind('$customer')
->group(
_id: '$customer_id',
totalSpent: Accumulator::sum('$amount'),
orderCount: Accumulator::count(),
lastOrder: Accumulator::max('$created_at'),
)
->sort(totalSpent: -1)
->limit(10)
->getPipeline()
);
// Single field index
$users->createIndex(['email' => 1]); // 'email_1'
// Compound index
$users->createIndex(['status' => 1, 'created_at' => -1]); // 'status_1_created_at_-1'
// Unique index
$users->createIndex(['email' => 1], ['unique' => true]);
// Named index
$users->createIndex(['email' => 1], ['name' => 'custom_idx']); // 'custom_idx'
// Text index
$users->createIndex(['content' => 'text']);
// TTL index (auto-expire documents)
$users->createIndex(['expires_at' => 1], ['expireAfterSeconds' => 3600]);
// Sparse index
$users->createIndex(['optional_field' => 1], ['sparse' => true]);
// Multiple indexes at once
$names = $users->createIndexes([
['key' => ['name' => 1]],
['key' => ['age' => -1]],
['key' => ['status' => 1, 'name' => 1]],
]);
// ['name_1', 'age_-1', 'status_1_name_1']
// List all indexes
$indexes = $users->listIndexes();
// Drop indexes
$users->dropIndex('email_1');
$users->dropIndexes(); // drops all except _id
// Explain find
$plan = $users->explain(['status' => 'active']);
$plan = $users->explain(); // empty filter
// Via builder
$plan = $users->find()
->filter(['status' => 'active'])
->sort(['created_at' => -1])
->explain();
// Explain aggregation
$plan = $users->explainAggregate([
['$match' => ['status' => 'completed']],
['$group' => ['_id' => '$category', 'total' => ['$sum' => '$amount']]],
]);
$stream = $users->watch(
[['$match' => ['operationType' => 'insert']]], // pipeline filter
['maxAwaitTimeMS' => 1000], // options
);
foreach ($stream as $event) {
echo $event->operationType;
echo $event->fullDocument->name;
}
$doc = $users->findOne(['email' => '[email protected] ']);
// Property access (with type conversion)
$doc->name; // 'Omar'
$doc->age; // 30
$doc->active; // true
$doc->missing; // null (missing fields return null)
// Nested documents become Document instances
$doc->address->city; // 'Amman'
$doc->address->geo->lat; // 31.95
// Arrays stay as arrays
$doc->tags; // ['php', 'mongodb']
$doc->scores; // [95, 87, 92]
// Dates become DateTimeImmutable
$doc->created_at; // DateTimeImmutable
$doc->created_at->format('Y-m-d'); // '2026-04-04'
// ObjectId
$doc->id(); // ObjectId instance
echo $doc->_id; // '507f...' via __toString
// Existence checks
$doc->has('email'); // true
$doc->has('missing'); // false
isset($doc->email); // true
// Default values
$doc->get('role', 'user'); // 'user' if role is missing
$doc->get('name', 'Anonymous'); // 'Omar' (field exists)
// Plain PHP array — no Document objects, no BSON types
$array = $doc->toArray();
$array['address']['city']; // 'Amman' (plain array, not Document)
$array['_id']; // '507f...' (string, not ObjectId)
// JSON string
$json = $doc->toJson();
$json = $doc->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
// Raw data — no conversion, original BSON types preserved
$raw = $doc->getRaw();
$raw['_id']; // ObjectId instance
// ArrayAccess (read-only)
$doc['name']; // 'Omar'
isset($doc['name']); // true
$doc['name'] = 'x'; // throws LogicException ('Document is immutable')
unset($doc['name']); // throws LogicException
// JsonSerializable
json_encode($doc); // '{"_id":"507f...","name":"Omar",...}'
$cursor = $users->find()->filter(['status' => 'active'])->execute();
// Iterate
foreach ($cursor as $index => $doc) {
echo "$index: {$doc->name}";
}
// Collect all
$docs = $cursor->toArray(); // list<Document>
// First document
$first = $cursor->first(); // Document|null
// Lazy generator
$gen = $cursor->lazy();
foreach ($gen as $doc) { ... }
// Count (consumes the cursor)
$count = $cursor->count(); // int
use PHPdot\MongoDB\Filter\Filter;
$filter = Filter::new()
->eq('status', 'active')
->gte('age', 18)
->toArray();
// ['status' => 'active', 'age' => ['$gte' => 18]]
$users->find()->where(fn(Filter $f) => $f->eq('status', 'active')->gte('age', 18))->execute();
$users->updateOne()->where(fn(Filter $f) => $f->eq('name', 'Omar'))->update([...])->execute();
$users->deleteMany()->where(fn(Filter $f) => $f->lt('expires_at', $now))->execute();
$f->eq('status', 'active'); // status = 'active'
$f->ne('status', 'deleted'); // status != 'deleted'
$f->gt('age', 18); // age > 18
$f->gte('age', 18); // age >= 18
$f->lt('age', 65); // age < 65
$f->lte('age', 65); // age <= 65
// Range — operators stack on the same field
$f->gte('age', 18)->lte('age', 65);
// ['age' => ['$gte' => 18, '$lte' => 65]]
$f->in('status', ['active', 'pending']); // status in [...]
$f->nin('role', ['banned', 'suspended']); // status not in [...]
$f->all('tags', ['php', 'mongodb']); // array contains all
$f->size('tags', 3); // array has exactly 3 elements
$f->elemMatch('scores', ['$gte' => 80, '$lt' => 100]); // array element matches
$f->or(
Filter::new()->eq('role', 'admin'),
Filter::new()->gt('score', 90),
);
$f->and(
Filter::new()->eq('status', 'active'),
Filter::new()->gte('age', 18),
);
$f->nor(
Filter::new()->eq('status', 'banned'),
Filter::new()->eq('role', 'bot'),
);
$f->not('age', ['$gt' => 100]);
$f->exists('email'); // field exists
$f->exists('deletedAt', false); // field does not exist
$f->type('age', 'int'); // field is of BSON type
$f->regex('name', '^Omar', 'i'); // regex with flags
$f->regex('email', '@example\.com$');
$f->text('mongodb php'); // full-text search (
$f->near('location', [35.9, 31.9], maxDistance: 1000.0);
$f->near('location', [35.9, 31.9], maxDistance: 5000.0, minDistance: 100.0);
$f->raw(['$where' => 'this.age > 18']);
$f->raw(['age' => ['$mod' => [5, 0]]]);
use PHPdot\MongoDB\Logging\QueryLogger;
$logger = new QueryLogger(
maxEntries: 100, // ring buffer size (overwrites oldest when full)
slowThresholdMs: 50.0, // threshold for slow query flag
);
$db = new Database($connection, $logger);
// Use normally — all operations are logged
$db->collection('users')->findOne(['status' => 'active']);
$db->collection('users')->insertOne(['name' => 'Test']);
// Query the log
$logger->getAll(); // list<QueryLog>
$logger->getSlow(); // list<QueryLog> (only slow queries)
$logger->count(); // int
$logger->getSlowThreshold(); // float
$logger->clear(); // reset
// Each entry (readonly)
foreach ($logger->getAll() as $log) {
$log->operation; // 'findOne', 'insertOne', 'aggregate', etc.
$log->collection; // 'users'
$log->filter; // ['status' => 'active']
$log->durationMs; // 2.34
$log->slow; // false
}
use PHPdot\MongoDB\GridFS\Bucket;
$bucket = new Bucket($connection); // default 'fs' bucket
$bucket = new Bucket($connection, 'uploads'); // custom bucket name
$bucket = new Bucket($connection, 'uploads', [ // with options
'chunkSizeBytes' => 1048576,
]);
// Upload from stream
$source = fopen('/path/to/file.pdf', 'r');
$id = $bucket->uploadFromStream('document.pdf', $source, [
'metadata' => ['author' => 'Omar', 'type' => 'invoice'],
]);
fclose($source);
// Download to stream
$dest = fopen('/tmp/download.pdf', 'w');
$bucket->downloadToStream($id, $dest);
fclose($dest);
// Open streams directly
$readStream = $bucket->openDownloadStream($id);
$content = stream_get_contents($readStream);
fclose($readStream);
$writeStream = $bucket->openUploadStream('output.txt');
fwrite($writeStream, 'Hello, GridFS!');
fclose($writeStream);
// Find files
$files = $bucket->find(); // all files
$files = $bucket->find(['filename' => 'document.pdf']); // with filter
// Manage
$bucket->rename($id, 'renamed.pdf');
$bucket->delete($id);
$bucket->drop(); // drop entire bucket (files + chunks)
$bucket->raw(); // MongoDB\GridFS\Bucket escape hatch
use PHPdot\MongoDB\Exception\DuplicateKeyException;
use PHPdot\MongoDB\Exception\ValidationException;
use PHPdot\MongoDB\Exception\TimeoutException;
use PHPdot\MongoDB\Exception\WriteException;
use PHPdot\MongoDB\Exception\QueryException;
use PHPdot\MongoDB\Exception\ConnectionException;
use PHPdot\MongoDB\Exception\MongoException;
try {
$users->insertOne(['email' => '[email protected] ']);
} catch (DuplicateKeyException $e) {
// Unique index violation
$e->getCollection(); // 'users'
$e->getDuplicateKey(); // 'email_1'
$e->getCode(); // 11000
$e->getPrevious(); // original MongoDB\Driver\Exception\RuntimeException
} catch (ValidationException $e) {
// Server-side schema validation failed
$e->getCollection(); // 'users'
$e->getCode(); // 121
} catch (TimeoutException $e) {
// Operation exceeded maxTimeMS
$e->getOperation(); // 'insertOne'
$e->getCollection(); // 'users'
} catch (WriteException $e) {
// Any other write error
$e->getOperation();
$e->getCollection();
} catch (QueryException $e) {
// Read operation error
$e->getOperation();
$e->getCollection();
} catch (ConnectionException $e) {
// MongoConnection lost even after retry
$e->getHost();
} catch (MongoException $e) {
// Catch-all for any PHPdot MongoDB exception
}
$users->raw(); // MongoDB\Collection
$db->raw(); // MongoDB\Database
$connection->getClient(); // MongoDB\Client
$bucket->raw(); // MongoDB\GridFS\Bucket
final class FindQuery
filter(array $filter): self
where(callable(Filter): Filter $callback): self
projection(array $fields): self
sort(array $sort): self
limit(int $limit): self
skip(int $skip): self
hint(string|array $hint): self
collation(array $collation): self
maxTimeMS(int $ms): self
batchSize(int $size): self
allowDiskUse(bool $allow = true): self
comment(string $comment): self
session(Session $session): self
option(string $key, mixed $value): self
execute(): Cursor
first(): ?Document
count(): int
explain(): array
getFilter(): array
getOptions(): array
final class UpdateQuery
filter(array $filter): self
where(callable(Filter): Filter $callback): self
update(array $update): self
upsert(bool $upsert = true): self
arrayFilters(array $filters): self
hint(string|array $hint): self
collation(array $collation): self
session(Session $session): self
option(string $key, mixed $value): self
execute(): UpdateResult
getFilter(): array
getUpdate(): array
getOptions(): array
final class DeleteQuery
filter(array $filter): self
where(callable(Filter): Filter $callback): self
hint(string|array $hint): self
collation(array $collation): self
session(Session $session): self
option(string $key, mixed $value): self
execute(): DeleteResult
getFilter(): array
getOptions(): array
final class Bucket
__construct(MongoConnection $connection, string $bucketName = 'fs', array $options = [])
uploadFromStream(string $filename, mixed $source, array $options = []): ObjectId
downloadToStream(ObjectId $id, mixed $destination): void
openDownloadStream(ObjectId $id): mixed (resource)
openUploadStream(string $filename, array $options = []): mixed (resource)
delete(ObjectId $id): void
find(array $filter = [], array $options = []): CursorInterface
rename(ObjectId $id, string $newFilename): void
drop(): void
raw(): GridFSBucket