MongoDB\Driver\Cursor 클래스

(mongodb >=1.0.0)


소개

MongoDB\Driver\Cursor 클래스는 MongoDB 명령 또는 쿼리의 결과를 캡슐화하고 각각 MongoDB\Driver\Manager::executeCommand() 또는 MongoDB\Driver\Manager::executeQuery()에 의해 반환될 수 있습니다.


클래스 개요

final class MongoDB\Driver\Cursor implements MongoDB\Driver\CursorInterface, Iterator {
  /* Methods */
  final private __construct()
  public current(): array|object
  final public getId(): MongoDB\Driver\CursorId
  final public getServer(): MongoDB\Driver\Server
  final public isDead(): bool
  public key(): int
  public next(): void
  public rewind(): void
  final public setTypeMap(array $typemap): void
  final public toArray(): array
  public valid(): bool
}
                

변경 로그

버전 설명
PECL mongodb 1.9.0 Iterator를 구현합니다.
PECL mongodb 1.6.0 Traversable을 확장하는 MongoDB\Driver\CursorInterface를 구현합니다.

Examples

예제 #1 결과 집합 읽기

MongoDB\Driver\Manager::executeCommand()MongoDB\Driver\Manager::executeQuery()는 모두 결과를 MongoDB\Driver\Cursor 객체로 반환합니다. 이 개체는 명령 또는 쿼리의 결과 집합을 반복하는 데 사용할 수 있습니다.

MongoDB\Driver\CursorTraversable 인터페이스를 구현하므로 foreach를 사용하여 결과 집합을 간단히 반복할 수 있습니다.

                  
<?php

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

/* Insert some documents so that our query returns information */
$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 for all the items in the collection */
$query = new MongoDB\Driver\Query( [] );

/* Query the "asteroids" collection of the "test" database */
$cursor = $manager->executeQuery("test.asteroids", $query);

/* $cursor now contains an object that wraps around the result set. Use
 * foreach() to iterate over all the result */
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 테일러블 커서에 대한 결과 세트 읽기

» Tailable 커서는 클라이언트가 일부 결과를 읽은 다음 더 많은 문서를 사용할 수 있을 때까지 기다릴 수 있는 특수한 유형의 MongoDB 커서입니다. 이 커서는 주로 » Capped Collections» Change Streams와 함께 사용됩니다.

일반 커서는 foreach를 사용하여 한 번 반복할 수 있지만 해당 접근 방식은 tailable 커서에서는 작동하지 않습니다. foreach가 tailable 커서와 함께 사용되면 루프는 초기 결과 집합의 끝에 도달하면 중지됩니다. PHP가 커서를 되감기를 시도하기 때문에 두 번째 foreach로 커서에서 반복을 계속하려고 하면 예외가 발생합니다. 다른 데이터베이스 드라이버의 결과 개체와 유사하게 MongoDB의 커서는 순방향 반복만 지원하므로 되돌릴 수 없습니다.

Tailable 커서에서 계속 읽으려면 Cursor 객체를 IteratorIterator로 래핑해야 합니다. 이를 통해 응용 프로그램은 커서의 반복을 직접 제어하고, 실수로 커서를 되감는 것을 방지하고, 언제 새 결과를 기다릴지 또는 반복을 완전히 중지할지 결정할 수 있습니다.

Tailable 커서가 작동하는 모습을 보여주기 위해 "생산자"와 "소비자"라는 두 가지 스크립트가 사용됩니다. 생산자 스크립트는 » 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);
}

?>
                  
                

생산자 스크립트가 계속 실행 중인 상태에서 두 번째 소비자 스크립트를 실행하여 MongoDB\Driver\Query::__construct()에 대한 tailableawaitData 옵션으로 표시된 tailable 커서를 사용하여 삽입된 문서를 읽을 수 있습니다.

                  
<?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("Consumed document created at: %s\n", $document->createdAt);
    }

    $iterator->next();
}

?>
                  
                

소비자 스크립트는 capped 컬렉션에서 사용 가능한 모든 문서를 빠르게 인쇄하여 시작합니다(foreach가 사용된 것처럼). 그러나 초기 결과 집합의 끝에 도달하면 종료되지 않습니다. 커서가 꼬리 가능하므로 IteratorIterator::next()를 호출하면 차단되고 추가 결과가 나올 때까지 기다립니다. IteratorIterator::valid()는 각 단계에서 읽을 수 있는 데이터가 실제로 있는지 확인하는 데에도 사용됩니다.

참고: 이 예에서는 awaitData 쿼리 옵션을 사용하여 드라이버에 응답을 반환하기 전에 결과 집합의 끝에서 짧은 기간(예: 1초) 동안 차단하도록 서버에 지시합니다. 이것은 사용 가능한 결과가 없을 때 드라이버가 적극적으로 서버를 폴링하는 것을 방지하는 데 사용됩니다. maxAwaitTimeMS 옵션은 tailableawaitData와 함께 사용하여 결과 집합의 끝에 도달했을 때 서버가 차단해야 하는 시간을 지정할 수 있습니다.


오류/예외

커서 객체를 반복할 때 BSON 데이터는 PHP 변수로 변환됩니다. 이 반복으로 인해 다음 예외가 발생할 수 있습니다.


목차