Класс MongoDB\Driver\Cursor
(mongodb >=1.0.0)
Введение
Класс MongoDB\Driver\Cursor содержит результаты команды MongoDB command или запроса и может быть возвращен MongoDB\Driver\Manager::executeCommand() или MongoDB\Driver\Manager::executeQuery() соответственно.
Обзор классов
Список изменений
Версия | Описание |
---|---|
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( [] );
/* Запрос коллекции "asteroids" базы данных "test" */
$cursor = $manager->executeQuery("test.asteroids", $query);
/* Теперь $cursor содержит объект, обернутый вокруг набора с результатом. Используйте
* foreach() для итеации по всему результату */
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. Эта итерация может вызвать следующие исключения:
- Выбрасывает MongoDB\Driver\Exception\InvalidArgumentException, если класс на карте типов не может быть создан или не реализует MongoDB\BSON\Unserializable.
- Исключение MongoDB\Driver\Exception\UnexpectedValueException выбрасывается, если входные данные не являются ровно одним документом BSON. Возможные причины включают, но не ограничены некоррекстным BSON, лишними данными или неожиданной ошибкой » libbson.
Содержание
- MongoDB\Driver\Cursor::__construct — Создает новый объект Cursor (не используется)
- MongoDB\Driver\Cursor::current — Возвращает текущий элемент
- MongoDB\Driver\Cursor::getId — Возвращает идентификатор для курсора
- MongoDB\Driver\Cursor::getServer — Возвращает сервер, связанный с курсором
- MongoDB\Driver\Cursor::isDead — Проверяет, исчерпан ли курсор или может содержать дополнительные результаты
- MongoDB\Driver\Cursor::key — Возвращает индекс текущего результата в курсоре
- MongoDB\Driver\Cursor::next — Перемещает курсор на следующий результат
- MongoDB\Driver\Cursor::rewind — Перемещает курсор к первому результату
- MongoDB\Driver\Cursor::setTypeMap — Устанавливает карту типа для десериализации BSON
- MongoDB\Driver\Cursor::toArray — Возвращает массив, содержащий все результаты курсора
- MongoDB\Driver\Cursor::valid — Проверяет, корректна ли текущая позиция курсора