Класс MongoDB\Driver\Cursor

(mongodb >=1.0.0)

Введение

Класс MongoDB\Driver\Cursor содержит результаты команды MongoDB command или запроса и может быть возвращён MongoDB\Driver\Manager::executeCommand() или MongoDB\Driver\Manager::executeQuery() соответственно.

Обзор классов

finalclassMongoDB\Driver\CursorimplementsMongoDB\Driver\CursorInterface, Iterator {
finalprivate__construct()
finalpublicisDead(): bool
publickey(): int
publicnext(): void
publicrewind(): void
finalpublicsetTypeMap(array$typemap): void
finalpublictoArray(): array
publicvalid(): bool
}

Список изменений

ВерсияОписание
PECL mongodb 1.9.0 Реализует Iterator.
PECL mongodb 1.6.0 Реализует MongoDB\Driver\CursorInterface, который наследует Traversable.

Примеры

Пример #1 Reading a result set

Как MongoDB\Driver\Manager::executeCommand(), так MongoDB\Driver\Manager::executeQuery(), возвращают свои результаты в виде объекта MongoDB\Driver\Cursor.

Поскольку MongoDB\Driver\Cursor реализует интерфейс Traversable, вы можете итерировать по набору результата с помощью foreach.

<?php

$manager
= new MongoDB\Driver\Manager();


$bulkWrite = new MongoDB\Driver\BulkWrite;
$bulkWrite->insert(['name' => 'Ceres', 'size' => 946, 'distance' => 2.766]);
$bulkWrite->insert(['name' => 'Vesta', 'size' => 525, 'distance' => 2.362]);
$manager->executeBulkWrite("test.asteroids", $bulkWrite);


$query = new MongoDB\Driver\Query( [] );


$cursor = $manager->executeQuery("test.asteroids", $query);


foreach ($cursor as $document) {
print_r($document);
}

?>

Вывод приведённого примера будет похож на:

 stdClass Object ( [_id] => MongoDB\BSON\ObjectId Object ( [oid] => 5a4cff2f122d3321565d8cc2 ) [name] => Ceres [size] => 946 [distance] => 2.766 ) stdClass Object ( [_id] => MongoDB\BSON\ObjectId Object ( [oid] => 5a4cff2f122d3321565d8cc3 ) [name] => Vesta [size] => 525 [distance] => 2.362 } 

Пример #2 Чтение набора результатов для хвостового курсора

» Хвостовые курсоры - - это особый тип курсора MongoDB, который позволяет клиенту читать некоторые результаты, а затем ждать, пока не появятся дополнительные документы. Эти курсоры в основном используются с » Capped Collections и » Change Streams.

Хотя обычные курсоры можно итерировать один раз с помощью foreach, этот подход не будет работать с хвостовыми курсорами. Когда foreach используется с хвостовым курсором, цикл останавливается по достижении конца начального набора результатов. Попытка продолжить итерацию курсора со вторым foreach выбросить исключение, поскольку PHP пытается перемотать курсор. Подобно объектам результатов в других драйверах баз данных, курсоры в MongoDB поддерживают только итерацию вперёд, что означает, что они не могут быть перемотаны.

Для непрерывного считывания с хвостового курсора объект курсора должен быть завернут с помощью IteratorIterator. Это позволяет приложению напрямую управлять итерацией курсора, избегать непреднамеренного перемотки курсора и решать, когда ждать новых результатов или полностью прекратить итерацию.

Чтобы продемонстрировать хвостовой курсор в действии, будут использоваться два скрипта: "производитель" (producer) и "потребитель" (consumer). Скрипт продюсера создаст новую capped-коллекцию, используя команду » create и начнёт вставку нового документа в эту коллекцию каждую секунду.

<?php

$manager
= new MongoDB\Driver\Manager;

$manager->executeCommand('test', new MongoDB\Driver\Command([
'create' => 'asteroids',
'capped' => true,
'size' => 1048576,
]));

while (
true) {
$bulkWrite = new MongoDB\Driver\BulkWrite;
$bulkWrite->insert(['createdAt' => new MongoDB\BSON\UTCDateTime]);
$manager->executeBulkWrite('test.asteroids', $bulkWrite);

sleep(1);
}

?>

Когда скрипт продюсера (producer) всё ещё запущен, может быть выполнен второй пользовательский скрипт для чтения вставленных документов с помощью хвостового (tailable) курсора, обозначенного параметрами tailable и awaitData для MongoDB\Driver\Query::__construct().

<?php

$manager
= new MongoDB\Driver\Manager;

$query = new MongoDB\Driver\Query([], [
'tailable' => true,
'awaitData' => true,
]);

$cursor = $manager->executeQuery('test.asteroids', $query);

$iterator = new IteratorIterator($cursor);

$iterator->rewind();

while (
true) {
if (
$iterator->valid()) {
$document = $iterator->current();
printf("Пользовательский документ создан: %s\n", $document->createdAt);
}

$iterator->next();
}

?>

Пользовательский скрипт начнёт с быстрой печати всех доступных документов в заблокированной коллекции (как если бы использовался foreach); однако при достижении конца начального набора результатов он не завершится. Так как курсор является хвостовым, вызов IteratorIterator::valid() будет блокировать и ждать дополнительных результатов. IteratorIterator::valid() также используется для проверки наличия на каждом этапе данных, доступных для чтения.

Замечание: В этом примере используется опция запроса awaitData, чтобы проинструктировать сервер блокировать в течение короткого периода (например, одну секунду) в конце набора результатов перед возвратом ответа драйверу. Это используется для предотвращения агрессивного опроса (polling) сервера при отсутствии результатов. Параметр maxAwaitTimeMS может использоваться в сочетании с tailable и awaitData, чтобы указать время, которое сервер должен блокировать, когда он достигнет конца набора результатов.

Ошибки

При итерации по объекту курсора данные BSON преобразуются в переменные PHP. Эта итерация может вызвать следующие исключения:

Содержание

To Top