SunshinePHP 2020 CFP Started

La classe MongoCursor

(PECL mongo >=0.9.0)

Introduction

Un curseur est utilisé pour itérer les résultats d'une requête. Par exemple regarder tous les résultats d'une requête quelconque :

Exemple #1 Utilisation basique de MongoCursor

<?php

$cursor 
$collection->find();
var_dump(iterator_to_array($cursor));

?>

En général, vous ne créez pas de MongoCursor en utilisant le constructeur mais en appelant MongoCollection::find() (comme ci-dessus).

Supposons que, dans l'exemple ci-dessus, $collection pèse 50Go. On ne voudra certainement pas tout charger en mémoire, c'est ce que permet un curseur : permettre au client d'accéder aux données au fur et à mesure.

Si nous avons des jeux de résultats très grands, nous pouvons itérer dessus, ceci chargera seulement quelques méga-octets dans la mémoire. Par exemple :

Exemple #2 Parcourt d'un MongoCursor

<?php

$cursor 
$collection->find();

foreach (
$cursor as $doc) {
    
// faire quelque chose avec chaque document $doc
}

?>
Les documents ici sont créés puis détruits au fur et à mesure de l'itération.

Notez que cela signifie qu'un curseur ne contient pas les données du jeu de résultats, il ne fait que les piloter. Ainsi si vous affichez un curseur (par exemple, avec var_dump() ou print_r()), vous n'obtiendrez que l'objet curseur, pas les documents. Pour obtenir les documents, vous pouvez utiliser une des techniques ci-dessus.

Etats des curseurs

Un MongoCursor a 2 états différents : Avant et après la requête. Lorsqu'un curseur est créé, il n'a pas encore contacté la base de données, il est en état pré-requête et le client peut toujours préciser ce qu'il attend de la requête, par exemple ajouter des limites, des tris ou encore des options avancées.

Lorsque le client tente de récupérer un résultat (en appelant la fonction MongoCursor::next(), directement ou indirectement), le curseur passe à l'état post-requête. À ce moment-là, la requête a été exécutée par la base et ne peut plus être modifiée.

Exemple #3 Ajout d'options à MongoCursor

<?php

$cursor 
$collection->find()->limit(10);

// la base n'a pas encore été interrogée,
// il est donc encore temps d'ajouter des options
$cursor $cursor->sort(array("a" => 1));

var_dump($cursor->getNext());
// maintenant, la base a été interrogée, et les options ne sont plus prises en compte

// Cet commnande va produire une exception :
$cursor->skip(4);
?>

Synopsis de la classe

MongoCursor implements MongoCursorInterface , Iterator {
/* Champs statiques */
static boolean $slaveOkay = FALSE ;
static integer $timeout = 30000 ;
/* Méthodes */
public addOption ( string $key , mixed $value ) : MongoCursor
public awaitData ([ bool $wait = TRUE ] ) : MongoCursor
public batchSize ( int $batchSize ) : MongoCursor
public __construct ( MongoClient $connection , string $ns [, array $query = array() [, array $fields = array() ]] )
public count ([ bool $foundOnly = FALSE ] ) : int
public current ( void ) : array
public dead ( void ) : bool
protected doQuery ( void ) : void
public explain ( void ) : array
public fields ( array $f ) : MongoCursor
public getNext ( void ) : array
public getReadPreference ( void ) : array
public hasNext ( void ) : bool
public hint ( mixed $index ) : MongoCursor
public immortal ([ bool $liveForever = TRUE ] ) : MongoCursor
public info ( void ) : array
public key ( void ) : string|int
public limit ( int $num ) : MongoCursor
public maxTimeMS ( int $ms ) : MongoCursor
public next ( void ) : array
public partial ([ bool $okay = TRUE ] ) : MongoCursor
public reset ( void ) : void
public rewind ( void ) : void
public setFlag ( int $flag [, bool $set = TRUE ] ) : MongoCursor
public setReadPreference ( string $read_preference [, array $tags ] ) : MongoCursor
public skip ( int $num ) : MongoCursor
public slaveOkay ([ bool $okay = TRUE ] ) : MongoCursor
public snapshot ( void ) : MongoCursor
public sort ( array $fields ) : MongoCursor
public tailable ([ bool $tail = TRUE ] ) : MongoCursor
public timeout ( int $ms ) : MongoCursor
public valid ( void ) : bool
}

Variables statiques

slaveOkay

Est ce que la requête doit avoir le drapeau "slaveOkay" activé, ce qui permet des lectures sur le secondaire (les secondaires sont par défaut déstinés à des sauvegardes et donc inaccessibles en lectures). Peut être surchargé avec MongoCursor::slaveOkay().

Cette fonctionalité est obsolète. Veuillez utiliser Préférences de lecture à la place.

timeout

Affecte le timeout en millisecondes pour les réponses des bases de données. Pour un timeout infini, utilisez -1. Peut être surchargé avec MongoCursor::timeout(). Ceci ne provoque pas une annulation de l'opération par le serveur MongoDB mais fait en sorte que le pilote s'arrête d'attendre une réponse et envoie une exception MongoCursorTimeoutException.

Voir aussi

Documentation de MongoDB » concernant les curseurs.

Sommaire

add a note add a note

User Contributed Notes 4 notes

up
9
adrian dot zurek at netmedia dot com dot pl
7 years ago
One *VERY* important note, if You do:
$cursor = $collection->find(array(), array('_id' => 0)); // ommit '_id' field in result

then:
var_dump(iterator_to_array($cursor));

will return only *ONE* document, not all!
up
2
alex
1 year ago
Deprecated:
$cursor = $collection->find();
$cursor->limit(1);

Use instead:
$collection->find([], [ 'limit' => 1 ]);
up
1
Adil Baig @ AiDezigns
7 years ago
If you want to know whether a cursor returned any results it is faster to use 'hasNext()' than 'count'
up
0
Adil Baig
4 years ago
The documentation says $timeout is a static variable that can be set:

"Set timeout in milliseconds for all database responses."

This feature has been deprecated. Attempting to set it will result in a warning :

"PHP Deprecated:  MongoCollection::find(): The 'MongoCursor::$timeout' static property is deprecated, please call MongoCursor->timeout() instead"
To Top